2

This is quite complicated to explain, so I will do my best, sorry if there is anything I missed out, let me know and I will rectify it.

My question is, I have been tasked to draw this shape,

Crescent Moon
(source: learnersdictionary.com)

This is to be done using C++ to write code that will calculate the points on this shape.

Important details.

User Input - Centre Point (X, Y), number of points to be shown, Font Size (influences radius)

Output - List of co-ordinates on the shape.

The overall aim once I have the points is to put them into a graph on Excel and it will hopefully draw it for me, at the user inputted size!

I know that the maximum Radius is 165mm and the minimum is 35mm. I have decided that my base Font Size shall be 20. I then did some thinking and came up with the equation.

Radius = (Chosen Font Size/20)*130. This is just an estimation, I realise it probably not right, but I thought it could work at least as a template.

I then decided that I should create two different circles, with two different centre points, then link them together to create the shape. I thought that the INSIDE line will have to have a larger Radius and a centre point further along the X-Axis (Y staying constant), as then it could cut into the outside line.

So I defined 2nd Centre point as (X+4, Y). (Again, just estimation, thought it doesn't really matter how far apart they are).

I then decided Radius 2 = (Chosen Font Size/20)*165 (max radius)

So, I have my 2 Radii, and two centre points.

Now to calculate the points on the circles, I am really struggling. I decided the best way to do it would be to create an increment (here is template)

for(int i=0; i<=n; i++) //where 'n' is users chosen number of points
{ 
  //Equation for X point
  //Equation for Y Point
  cout<<"("<<X<<","<<Y<<")"<<endl;
}

Now, for the life of me, I cannot figure out an equation to calculate the points. I have found equations that involve angles, but as I do not have any, I'm struggling.

I am, in essence, trying to calculate Point 'P' here, except all the way round the circle. Points on a circle
(source: tutorvista.com)

Another point I am thinking may be a problem is imposing limits on the values calculated to only display the values that are on the shape.? Not sure how to chose limits exactly other than to make the outside line a full Half Circle so I have a maximum radius?

So. Does anyone have any hints/tips/links they can share with me on how to proceed exactly?

Thanks again, any problems with the question, sorry will do my best to rectify if you let me know.

Cheers

UPDATE;

R1 = (Font/20)*130;
R2 = (Font/20)*165;

for(X1=0; X1<=n; X1++)
{
    Y1 = ((2*Y)+(pow(((4*((pow((X1-X), 2)))+(pow(R1, 2)))), 0.5)))/2;
    Y2 = ((2*Y)-(pow(((4*((pow((X1-X), 2)))+(pow(R1, 2)))), 0.5)))/2;
    cout<<"("<<X1<<","<<Y1<<")";
    cout<<"("<<X1<<","<<Y2<<")";
}

Opinion?

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Craig
  • 65
  • 2
  • 9
  • What determines where the intersection points are? Is it arbitrary? – JBentley Mar 26 '13 at 00:35
  • Or to put it a better way, what are the precise criteria for a valid shape? – JBentley Mar 26 '13 at 00:35
  • Also, (in the absense of precise criteria), I don't see why the radius needs to be larger for the inner segment? A larger circle could intersect the outer one just as easily as a smaller circle. – JBentley Mar 26 '13 at 00:36
  • @JBentley My assumption is that they are two circles with a given center and radius. – Code-Apprentice Mar 26 '13 at 00:36
  • I thought that if I made the outside line a half circle, of which you would then know the radius of using the equations shown above, then the inside line could intersect at the start and end points (which could easily be calculated) of the half circle? Because then I could limit the Y- values the inside line could go to? That help? – Craig Mar 26 '13 at 00:38
  • @Code-Guru Well I ask because the question states that the user input is only the center point, number of points, and font size - so it I'm not sure how this is determined at runtime. – JBentley Mar 26 '13 at 00:38
  • @Craig To me, the inside arc looks closer to a semi-circle than the outside one... – Code-Apprentice Mar 26 '13 at 00:40
  • Yeah, the result does not have to be exactly like the picture, the picture just displays the inner arc as such, it was just a thought I had with the outer circle being larger thats all. I was going to use my equation shown above to calculate the inner radius? – Craig Mar 26 '13 at 00:43
  • @Craig see my answer for how to calculate the second arc. – JBentley Mar 26 '13 at 00:50
  • @Code-Guru Using Algrebra for the equation above, I managed to get x = h - R^2-R. I don't know if this is right, but I just used pen and paper and worked through it. Thanks for the help, going to try and look at it all now. What do you mean by 'incrementing by some appropriate delta' though? – Craig Mar 26 '13 at 01:09
  • @Craig Can you edit your original question (or maybe post a new Q) to show how you derived that equation? – Code-Apprentice Mar 26 '13 at 01:13
  • Assuming you did the algebra correct, then your equation gives a single value of x for the chosen value of y. In other words, you have calculated **one** point on the circle. In order to draw the circle, you need a lot more than just this one point. This means that you need an equation where you can give it **any** value of x and it will spit out the corresponding value of y. (You can choose y and calculate x if you want. The math is the same. It's usually standard to pick x and calculate y.) – Code-Apprentice Mar 26 '13 at 01:26
  • Also, after looking at your loop, it looks like you are calculating the same two values over and over and over. Personally, I would change `i` to `x` and just calculate `y`. – Code-Apprentice Mar 26 '13 at 01:31

2 Answers2

2

The equation of a circle is

(x - h)^2 + (y - k)^2 = r^2

With a little bit of algebra, you can iterate x over the range from h to h+r incrementing by some appropriate delta and calculate the two corresponding values of y. This will draw a complete circle.

The next step is to find the x-coordinate for the intersection of the two circles (assuming that the moon shape is defined by two appropriate circles). Again, some algebra and a pencil and paper will help.

More details:

To draw a circle without using polar coordinates and trig, you can do something like this:

for x in h-r to h+r increment by delta
    calculate both y coordinates

To calculate the y-coordinates, you need to solve the equation of a circle for y. The easiest way to do this is to transform it into a quadratic equation of the form A*y^2+B*y+C=0 and use the quadratic equation:

(x - h)^2 + (y - k)^2 = r^2
(x - h)^2 + (y - k)^2 - r^2 = 0
(y^2 - 2*k*y + k^2) + (x - h)^2  - r^2 = 0
y^2 - 2*k*y + (k^2 + (x - h)^2  - r^2) = 0

So we have

A = 1
B = -2*k
C = k^2 + (x - h)^2  - r^2

Now plug these into the quadratic equation and chug out the two y-values for each x value in the for loop. (Most likely, you will want to do the calculations in a separate function -- or functions.)

As you can see this is pretty messy. Doing this with trigonometry and angles will be much cleaner.

More thoughts:

Even though there are no angles in the user input described in the question, there is no intrinsic reason why you cannot use them during calculations (unless you have a specific requirement otherwise, say because your teacher told you not to). With that said, using polar coordinates makes this much easier. For a complete circle you can do something like this:

for theta = 0 to 2*PI increment by delta
    x = r * cos(theta)
    y = r * sin(theta)

To draw an arc, rather than a full circle, you simply change the limits for theta in the for loop. For example, the left-half of the circle goes from PI/2 to 3*PI/2.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • @Craig When I wrote "iterate x...", I had a for loop in mind. You need to decide how much to increment x. You can simply increment by 1 (++x) or by some other value (x += delta) depending on the units you are using and how close of an approximation you need to an actual circle. – Code-Apprentice Mar 26 '13 at 01:08
  • @Craig Your earlier comment disappeared before I had a chance to comment on how you solved the equation. I assume you found a problem with the result. For one thing, I didn't see any y value in the result. Keep us updated with what you figure our, especially if you need more help. – Code-Apprentice Mar 26 '13 at 01:11
  • Ah! I get it now, wasn't really understanding calculating two values for Y for every x value...Sorry getting late, mind not focussed right. Sorry about that. But yeah thanks, will give that a go and see what happens. Agree the quadratic may be messy but at least I know that I will get two (hopefully) correct values. Thanks again, will keep you posted as I go. – Craig Mar 26 '13 at 01:38
  • @Craig I have edited my answer with some thoughts about using trig to solve your problem. If you understand the basics, this is much cleaner than using the quadratic formula. – Code-Apprentice Mar 26 '13 at 16:02
  • Using your latest bit of code, is there any way to chose the number of points chosen? The code works, but only displays 4 points – Craig Mar 27 '13 at 22:24
  • @Craig The number of points depends on what value you choose for `delta`. Since you only get four points, `delta` is set to `PI/2`. To determine the correct value for `delta` simply divide `2*PI` by the number of points you want. – Code-Apprentice Mar 28 '13 at 22:48
2

As per Code-Guru's comments on the question, the inner circle looks more like a half circle than the outer. Use the equation in Code-Guru's answer to calculate the points for the inner circle. Then, have a look at this question for how to calculate the radius of a circle which intersects your circle, given the distance (which you can set arbitrarily) and the points of intersection (which you know, because it's a half circle). From this you can draw the outer arc for any given distance, and all you need to do is vary the distance until you produce a shape that you're happy with.

This question may help you to apply Code-Guru's equation.

Community
  • 1
  • 1
JBentley
  • 6,099
  • 5
  • 37
  • 72
  • I'm struggling to create an increment that will go through all the values in the circle. Any other hints? – Craig Mar 26 '13 at 01:09
  • @Craig What do you mean by "all the values in the circle"? – Code-Apprentice Mar 26 '13 at 01:11
  • @Craig What Code-Guru is saying is that a circle has an infinite number of points. You need to decide on what is a reasonable number of points to display, and then only calculate those. – JBentley Mar 26 '13 at 01:12
  • @Craig I've edited my answer with a question which may help you work through Code-Guru's equation. – JBentley Mar 26 '13 at 01:18
  • @JBentley Thanks again. Going to head to bed now but will keep you posted on the work. cheers – Craig Mar 26 '13 at 01:32