c++mathgeometryellipsedrawellipse

How can I draw an ellipse based on four rotated and scaled points?


I start with a perfect circle, and then I need to rotate and scale it free without loose the ellipse characteristics:

Circle distortion

I would like to know if there is a way to describe a ellipse distorted like that based only in cosines and sines.

I have this code:

    float centerX = 100;
    float centerY = 100;
    float radiusX = 100;
    float radiusY = 100;
    float rotation = PI;
    float res = 30;
    for (int i = 0; i < res; i++) {

        //find the point in space for the circle resolution
            float angle = (float)i/res * TWO_PI;

            float x = radiusX * cos(angle);
            float y = -radiusY * sin(angle);

        //rotate the point
            float s = sin(rotation);
            float c = cos(rotation);

            // translate point to origin:
            p->x -= centerX;
            p->y -= centerY;

            float xnew = p->x * c - p->y * s;
            float ynew = p->x * s + p->y * c;

            // translate point back
            x = xnew + centerX;
            y = ynew + centerY;

        //apply X Y
    }

This code can only represent the same ellipse ignoring the relation between the rotation and scale:

enter image description here


Solution

  • I used the same method I alread askt here years ago, but that time it was usefull to distort a square: What's the correct way to draw a distorted plane in OpenGL?

    Here is the code:

    //setup the four coordinates
    float topX = 20;
    float topY = 10;
    
    float bottomX = 30;
    float bottomY = 20;
    
    float rightX = 30;
    float rightY = 20;
    
    float leftX = 30;
    float leftY = 20;
    
    //calculate the horizontal radius
    float distHorX = rightX-leftX;
    float distHorY = rightY-leftY;
    float radiusX = sqrt(distHorX * distHorX + distHorY * distHorY)/2.f;
    
    //calculate the vertical radius
    float distVerX = topX-bottomX;
    float distVerY = topY-bottomY;
    radiusY = sqrt(distVerX * distVerX + distVerY * distVerY)/2.f;
    
    float res = 30;
    for (int i = 0; i < res; i++) {
    
            float angle = (float)i/res * TWO_PI;
    
            float x = radiusX * cos(angle);
            float y = -radiusY * sin(angle);
    
            //corvert the circle inside a square to a square inside a circle
            //it is a magical number I have found to convert that proportion
            x /= 0.705069124;
            y /= 0.705069124;
    
            //transform the points based on that four coordinates
            float pctx = (x + radiusX) / (radiusX*2);
            float pcty = (y + radiusY) / (radiusY*2);
    
            float linePt0x = (1-pcty)* topX + pcty * leftX;
            float linePt0y = (1-pcty)* topY + pcty * leftY;
            float linePt1x = (1-pcty)* rightX + pcty * bottomX;
            float linePt1y = (1-pcty)* rightY + pcty * bottomY;
            float ptx      = (1-pctx) * linePt0x + pctx * linePt1x;
            float pty      = (1-pctx) * linePt0y + pctx * linePt1y;
    
            //apply X Y
            x = ptx;
            y = pty;
        }