I'm having an issue with drawing an ellipse object using OpenGL (sharpgl to be exact since it works well enough with WPF).
Right now I'm using this code (angles are in degrees):
gl.Begin(OpenGL.GL_LINE_STRIP);
gl.Color(colorR, colorG, colorB, alfa);
for (double i = angleStart; i <= angleEnd; ++i)
{
double angleCurrent = Math.PI * i / 180;
double dx = radiusX * Math.Cos(angleCurrent);
double dy = radiusY * Math.Sin(angleCurrent);
gl.Vertex(dx + ellipseMiddleCoordX, dy + ellipseMiddleCoordY, 0);
}
gl.End();
And it works 100% fine for drawing circles (that is radiusX = radiusY) and ellipses where angles are 0, 90, 180, 270, 360 (radiusX != radiusY).
However it doesn't quite do the job when radiusX != radiusY and for example angleStart = 30; angleEnd = 70.
What it does for above example it draws a circle first, apply the angles, then recalculates the X/Y radius. This gives incorrect results since I expect something like this:

where red = expected behaviour, yellow = code above, grey = additional lines for angles
I'm quite lost on how I'm suppose to approach the fix in this.
P.S.
yes - I know that gl.Begin/gl.End are outdated functions, but I still fail to grasp the full concept of OGL, and most of my program is just math.
That is because the elliptic parametric angle is not geometric angle as it is distorted by the different scale (radius) in each axis. See these related QAs for some inspiration:
The way to solve this is ether approximate the distortion (but that will beproblematic if eccentricity change a lot) or search for correct angle (simple but slow) or compute it analytically (involves some math but fast).
For the search you can use binary search for this just take in mind the geometric angle will be bigger than parametric one on some quadrants and less on the others.
Here small C++/OpenGL example (unsophisticated and unoptimized to keep it as simple as possible):
where
xs,ysis the resolution of my OpenGL window andM_PI=3.1415926535897932384626433832795note all angles are in radians.Here preview:
As you can see the angles match on the whole circumference (blue arcs align with yellow lines) ...
The function
float ellipse_angle(float rx,float ry,float ang)will return elliptic parametric angle that corresponds to geometric angleangon axis aligned ellipse with half axisesrx,ry.There are quite a few things that can improve speed of this like using
rx/ryand scaling just one axis, precompute the angle constants etc.[Edit1] slightly better code
using aspect ratio and render is changed too for better visual check
There still room for improvement like get rid of
atan2completely and use cross product instead like I did in here:[Edit2] Fast analytic
O(1)solutionI simply used parametric line equation:
and implicit ellipse equation:
to compute the intersection point (solve
tand computex,yfrom it), then apply inverse distortion on it to map from ellipse to circle (by scalingy*=rx/ry) and finally compute its angle withatan2(y,x).Here C++ code: