2010-04-25 15 views
6

Tengo tareas para escribir programas que permiten a los usuarios dibujar estrellas, que pueden diferir en tamaño y cantidad de brazos. Cuando yo estaba tratando con estrellas básicos que lo hacía con GeneralPath y tablas de puntos:Dibujando formas de estrella con parámetros variables

 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); 

¿Qué método debería elegir para dibujar estrellas con un radio interior y exterior variables, así como diferentes cantidades de armas? Esto es lo que debería obtener:

alt text http://img228.imageshack.us/img228/6427/lab6c.jpg

Respuesta

19

Tener n brazos que terminan con 2n vértices, las pares están en el círculo exterior, y los impares en el círculo interior. Visto desde el centro, los vértices están en ángulos uniformemente espaciados (el ángulo es 2 * PI/2 * n = Pi/n). En un círculo unitario (r = 1), las coordenadas x, y de los puntos i = 0..n es cos (x), sen (x). Multiplique esas coordenadas con el radio respectivo (rOuter o rInner, dependiendo de si es impar o par), y agregue ese vector al centro de la estrella para obtener las coordenadas para cada vértice en la trayectoria de la estrella.

Aquí está la función para crear una forma de estrella con determinado número de brazos, coordinar centro y, radio interior exterior:

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; 
} 
3

creo que debe usar las mismas clases (GeneralPath), pero en este caso usted debe centrarse en la forma de calcular las coordenadas del vértice.

Lo primero que me viene a la mente es posicionar 2N puntos en un círculo de radio R1, centrado en (0,0). Luego, "strech" cada vértice impar multiplicando su vector por c. La constante c debe ser igual a R2/R1 (es decir, la proporción de radios internos y externos). significa

Pero tal vez hay una solución más simple ...

2

He aquí un example de encontrar puntos igualmente espaciados sobre un circle que puede ayudar. Simplemente haga la cantidad de puntos, n, un parámetro en el 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; 
    ... 
}