1

I'm trying to write a code to draw an ellipse in XNA. Suppose we have the following parameters:

  1. Semi-major axis (a).
  2. Semi-minor axis (b).
  3. ellipse center (h,k).
  4. and 2D rotation (theta).

How it possible to draw the ellipse using the above parameters.

Here is the function

public VertexPositionColor Set2dEllipse(int x, int y, int z, Color color)
{
    VertexPositionColor vertices= new VertexPositionColor[100];
    for(int i= 0;i<100;i++)
    {
        double angle = (i / 100 * Math.PI * 2);
        vertices[i].Position = New Vector3((x + (Math.Cos(angle)) * size.Width), (y + Math.Sin(angle) * size.Height), z);
        vertices[i].Color = color;
    }
}
puretppc
  • 3,232
  • 8
  • 38
  • 65
CS2013
  • 133
  • 1
  • 5
  • 14

2 Answers2

2

I've modified the code taken from here to meet your requirements.

public void CreateEllipse(int a, int b, int h, int k, float theta)
{
    VertexPositionColor[] vertices = new VertexPositionColor[vertexCount];
    //Drawing an Ellipse with its major axis parallel to the x-axis. Rotation can be applied to change this.
    Vector3 position;
    const float max = MathHelper.Pi;
    //2 * max since we're moving from -Pi to +Pi in the loop.
    float step = 2 * max / (float)vertexCount;
    int i = 0;
    //Optional Axis and angle rotation for the ellipse (See later notes):
    //Vector3 axis = new Vector3(0, 0, -1);
    float angle = MathHelper.ToRadians(theta);

    for (float t = -max; t <= max; t += step)
    {
        //Formula shamelessly taken from wikipedia
        position = new Vector3(h + a * (float)Math.Cos((double)t), k + b * (float)Math.Sin((double)t), 0f);
        //Optional Rotation for the Ellipse:
        //position = Vector3.Transform(position, Matrix.CreateFromAxisAngle(axis, angle));
        vertices[i] = new VertexPositionColor(position, Color.DarkOrange);
        i++;
    }
    //Optional Rotation for the Ellipse:
    position = Vector3.Transform(position, Matrix.CreateFromAxisAngle(axis, angle));
    //then add the first vector again so it's a complete loop (sounds familiar)
    position = new Vector3(h + a * (float)Math.Cos((double)-max), k + b * (float)Math.Sin((double)-max), 0f);
    vertices[vertexCount - 1] = new VertexPositionColor(position, Color.DarkOrange);

    vertexBuffer = new VertexBuffer(device, vertexCount * VertexPositionColor.SizeInBytes,
        BufferUsage.WriteOnly);
    vertexBuffer.SetData<VertexPositionColor>(vertices);
}
Cyral
  • 13,999
  • 6
  • 50
  • 90
  • Thank you so much for the answer. But I got syntax error on the last line. `vertexCount * VertexPositionColor.SizeInBytes`. 'Microsoft.Xna.Framework.Graphics.VertexPositionColor' does not contain a definition for 'SizeInBytes'. Any idea? – CS2013 Feb 02 '14 at 16:30
  • How were you using the `VertexPositionColor vertices` before? Just draw it with what you used for your method before, TBH I'm not sure... – Cyral Feb 02 '14 at 16:57
  • This might help: http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series1/VertexBuffer_and_IndexBuffer.php – Cyral Feb 02 '14 at 17:05
0

You can find out the equation of the ellipse in terms of x or y alone. Then increment/decrement x or y to get the other coordinate based on the direction . Here's what i did for a circle

 this.x+=1.5*Gdx.graphics.getDeltaTime() * direction;

 if(direction==1)
 {

     if(this.x>=(centerx+radius))
    {


        direction=-1;
    }

 }

 else
 {

     if(this.x<=(centerx-radius))
        {


            direction=1;
        } 
 }

    this.y=(  (float) Math.sqrt(Math.abs(((radius*radius)- ( (this.x -centerx )*    (this.x -centerx )) )) )*direction  +  centery )  ;

PS: the code is in java for libgdx. You can adapt accordingly