Search code examples
iosmathcore-graphicsellipse

Issue with ellipse angle calculation and point calculation


I have a UIView with bounds (w, h) and I am trying to calculate angles and point on a ellipse which is centred at view's mid point i.e. centre is (w * 0.5, h * 0.5). I continuously change the size of view and ellipse so following values are from console for a instance of values.

For this instance, (w, h) = (150.000000, 300.799988) and radii are (rx, ry) = (52.500000, 105.279999)

Now, I try to find angle of point P1(x,y)(30.784275, 93.637390) on this ellipse using following code:

CGFloat angle = atan2((y - (h * 0.5)), (x - (w * 0.5)));
if (angle < 0)
{
   angle += 2 * M_PI;
}

The angle value I get is 4.050611.

Since I was not getting my desired output I just tried to find the point on ellipse from above angle using code below:

framePoint.x = (w * 0.5) + (rx * cosf(angle));
framePoint.y = (h * 0.5) + (ry * sinf(angle));

And surprisingly I got point as (42.737656,67.344543).

I just went ahead and did one more iteration of same process. I calculated angle from above point and got angle as 4.341885 and new point from this latest angle as (55.990501,52.263786).

I know something is wrong with my calculation formulas but I am not able to pin point it.

Also if above ellipse is a circle i.e. when rx = ry, all the points and angle are equal. So it kind of work for circle but not for ellipse.

So, I want to know exactly where I went wrong.


Solution

  • yes now I see it what you mean

    You are obtaining E angle from ellipse via E=atan2(...) and using it in equation where you need Mangle x=x0+rx*cos(M), y=... where:

    • M is mean circular angle
    • E is ellipse angle

    ellipse/circle angles

    It is analogy to Kepler's equation luckily for you you do not need to match speeds around main focus point so In order to obtain the M angle:

    1. scale one axis to convert ellipse to circle

    2. compute the angle there

      so if your axis aligned ellipse is (x0,y0,rx,ry) and input point on ellipse is (x1,y1) then if I am not mistaken it should be like this:

      M=atan2((y1-y0)*rx/ry,x1-x0)
      

      or

      M=atan2(y1-y0,(x1-x0)*ry/rx)
      
    3. compute your point using M

      x=x0+rx*cos(M)
      y=y0+ry*sin(M)
      

    [notes]

    • the X coordinate of both points should be the same (image was hand drawed in paint)
    • it does not matter which axis you scale and which not

    See also similar: