views:

253

answers:

3

Hi. I have task to write program allowing users to draw stars, which can differ in size and amount of arms. When I was dealing with basic stars I was doing it with GeneralPath and tables of points :

     int xPoints[] = { 55, 67, 109, 73, 83, 55, 27, 37, 1, 43 };
     int yPoints[] = { 0, 36, 36, 54, 96, 72, 96, 54, 36, 36 };
     Graphics2D g2d = ( Graphics2D ) g;
     GeneralPath star = new GeneralPath();
     star.moveTo( xPoints[ 0 ], yPoints[ 0 ] );
     for ( int k = 1; k < xPoints.length; k++ )
     star.lineTo( xPoints[ k ], yPoints[ k ] );
     star.closePath();
     g2d.fill( star );

What method should I choose for drawing stars with variable inner and outer radius, as well as different amount of arms ? This is what I should obtain :

alt text

+3  A: 

I think you should use the same classes (GeneralPath), but here you should focus on how to compute the vertex coordinates.

The first thing that comes to my mind is positioning 2N points on a circle of radius R1, centered at (0,0). Then, "strech" every odd vertex by multiplying its vector by c. The constant c should be equal to R2/R1 (i.e. the proportion of inner and outer radiuses).

But maybe there is a simpler solution...

Eyal Schneider
+2  A: 

Having n arms means you end up with 2n vertices, the even ones are on the outer circle, and the odd ones on the inner circle. Viewed from the center, the vertices are at evenly spaced angles (the angle is 2*PI/2*n = Pi/n). On an unit circle (r=1), the x,y coordinates of the points i=0..n is cos(x),sin(x). Multiply those coordinates with the respective radius (rOuter or rInner, depending of whether i is odd or even), and add that vector to the center of the star to get the coordinates for each vertex in the star path.

Here's the function to create a star shape with given number of arms, center coordinate and outer, inner radius:

public static Shape createStar(int arms, Point center, double rOuter, double rInner)
{
    double angle = Math.PI / arms;

    GeneralPath path = new GeneralPath();

    for (int i = 0; i < 2 * arms; i++)
    {
        double r = (i & 1) == 0 ? rOuter : rInner;
        Point2D.Double p = new Point2D.Double(center.x + Math.cos(i * angle) * r, center.y + Math.sin(i * angle) * r);
        if (i == 0) path.moveTo(p.getX(), p.getY());
        else path.lineTo(p.getX(), p.getY());
    }
    path.closePath();
    return path;
}
Peter Walser
A: 

Here's an example of finding equally spaced points on a circle that may help. Just make the number of points, n, a parameter in the constructor.

private int n;
...
public CircleTest(int n) {
    ...
    this.n = n;
}
...
for (int i = 0; i < n; i++) {
    double t = 2 * Math.PI * i / n;
    ...
}
trashgod