Chris Hutchinson
Chris Hutchinson

Reputation: 9212

Render ellipse using libgdx

I am attempting to render an ellipse using ShapeRenderer, and have come up with the following partial solution:

void drawEllipse(float x, float y, float width, float height) {
    float r = (width / 2);
    ShapeRenderer renderer = new ShapeRenderer();
    renderer.setProjectionMatrix(/* camera matrix */);
    renderer.begin(ShapeType.Circle);
    renderer.scale(1f, (height / width), 1f);
    renderer.circle(x + r, y, r);
    renderer.identity();
    renderer.end();
}

This draws an ellipse at the specified coordinates with the correct width and height; however, it appears that the scale transformation causes the circle to be translated in the viewport, and I have not been successful in determining the mathematics behind the translation. I am using an orthogonal projection with y-up where the coordinates map to a pixel on the screen. I am not very familiar with OpenGL.

How can I draw an ellipse using libgdx, and have it draw the ellipse at the exact coordinates I specify? Ideally, that would mean that the origin of the ellipse is located in the top-left corner, if the ellipse was contained in a rectangle.

Upvotes: 2

Views: 4195

Answers (1)

P.T.
P.T.

Reputation: 25177

The new Libgdx ShapeRenderer API (current nightlies, in whatever release will come after v0.9.8) contains an ellipse drawing method so you can ignore the rest of this answer. The ShapeRenderer method has changed in other ways, too though (e.g., the ShapeType is just Filled, Line, or Point now).

For folks stuck with the older API, you should be able to work-around the distortion by making sure the scaling happens around the origin. This is a standard OpenGL practice (so its a bit obtuse, but they're following OpenGL's lead). See Opengl order of matrix transformations and OpenGL: scale then translate? and how?. Even better (again standard OpenGL practice) you end up listing the operations in the reverse order you want them to happen at, so to make a circle, distort it into an ellipse, then move it to a specific destination you actually write code like:

renderer.begin(ShapeType.Circle);
renderer.translate(x, y, 0);
renderer.scale(1f, (height/width), 1f);
renderer.circle(0, 0, r);
renderer.end();

Upvotes: 1

Related Questions