package org.newdawn.slick.geom; import java.util.ArrayList; import org.newdawn.slick.util.FastTrig; /** * An ellipse meeting the <code>Shape</code> contract. The ellipse is actually an approximation using * a series of points generated around the contour of the ellipse. * * @author Mark */ public class Ellipse extends Shape { /** * Default number of segments to draw this ellipse with */ protected static final int DEFAULT_SEGMENT_COUNT = 50; /** * The number of segments for graphical representation. */ private int segmentCount; /** * horizontal radius */ private float radius1; /** * vertical radius */ private float radius2; /** * Creates a new Ellipse object. * * @param centerPointX x coordinate of the center of the ellipse * @param centerPointY y coordinate of the center of the ellipse * @param radius1 horizontal radius * @param radius2 vertical radius */ public Ellipse(float centerPointX, float centerPointY, float radius1, float radius2) { this(centerPointX, centerPointY, radius1, radius2, DEFAULT_SEGMENT_COUNT); } /** * Creates a new Ellipse object. * * @param centerPointX x coordinate of the center of the ellipse * @param centerPointY y coordinate of the center of the ellipse * @param radius1 horizontal radius * @param radius2 vertical radius * @param segmentCount how fine to make the ellipse. */ public Ellipse(float centerPointX, float centerPointY, float radius1, float radius2, int segmentCount) { this.x = centerPointX - radius1; this.y = centerPointY - radius2; this.radius1 = radius1; this.radius2 = radius2; this.segmentCount = segmentCount; checkPoints(); } /** * Change the shape of this Ellipse * * @param radius1 horizontal radius * @param radius2 vertical radius */ public void setRadii(float radius1, float radius2) { setRadius1(radius1); setRadius2(radius2); } /** * Get the horizontal radius of the ellipse * * @return The horizontal radius of the ellipse */ public float getRadius1() { return radius1; } /** * Set the horizontal radius of the ellipse * * @param radius1 The horizontal radius to set */ public void setRadius1(float radius1) { if (radius1 != this.radius1) { this.radius1 = radius1; pointsDirty = true; } } /** * Get the vertical radius of the ellipse * * @return The vertical radius of the ellipse */ public float getRadius2() { return radius2; } /** * Set the vertical radius of the ellipse * * @param radius2 The vertical radius to set */ public void setRadius2(float radius2) { if (radius2 != this.radius2) { this.radius2 = radius2; pointsDirty = true; } } /** * Generate the points to outline this ellipse. * */ protected void createPoints() { ArrayList tempPoints = new ArrayList(); maxX = -Float.MIN_VALUE; maxY = -Float.MIN_VALUE; minX = Float.MAX_VALUE; minY = Float.MAX_VALUE; float start = 0; float end = 359; float cx = x + radius1; float cy = y + radius2; int step = 360 / segmentCount; for (float a=start;a<=end+step;a+=step) { float ang = a; if (ang > end) { ang = end; } float newX = (float) (cx + (FastTrig.cos(Math.toRadians(ang)) * radius1)); float newY = (float) (cy + (FastTrig.sin(Math.toRadians(ang)) * radius2)); if(newX > maxX) { maxX = newX; } if(newY > maxY) { maxY = newY; } if(newX < minX) { minX = newX; } if(newY < minY) { minY = newY; } tempPoints.add(new Float(newX)); tempPoints.add(new Float(newY)); } points = new float[tempPoints.size()]; for(int i=0;i<points.length;i++) { points[i] = ((Float)tempPoints.get(i)).floatValue(); } } /** * @see org.newdawn.slick.geom.Shape#transform(org.newdawn.slick.geom.Transform) */ public Shape transform(Transform transform) { checkPoints(); Polygon resultPolygon = new Polygon(); float result[] = new float[points.length]; transform.transform(points, 0, result, 0, points.length / 2); resultPolygon.points = result; resultPolygon.checkPoints(); return resultPolygon; } /** * @see org.newdawn.slick.geom.Shape#findCenter() */ protected void findCenter() { center = new float[2]; center[0] = x + radius1; center[1] = y + radius2; } /** * @see org.newdawn.slick.geom.Shape#calculateRadius() */ protected void calculateRadius() { boundingCircleRadius = (radius1 > radius2) ? radius1 : radius2; } }