2010-04-25 34 views
6

Tôi có nhiệm vụ viết chương trình cho phép người dùng vẽ sao, có thể khác về kích thước và số lượng cánh tay. Khi tôi đang đối phó với các ngôi sao cơ bản tôi đã làm nó với GeneralPath và bảng điểm:Vẽ hình dạng ngôi sao với các thông số biến

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

phương pháp gì tôi nên chọn cho việc vẽ sao với bán kính bên trong và bên ngoài thay đổi, cũng như số tiền khác nhau của vũ khí? Đây là những gì tôi nên lấy:

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

Trả lời

19

Có n cánh tay có nghĩa là bạn kết thúc với đỉnh 2n, những người thậm chí là trên vòng tròn bên ngoài, và những người kỳ quặc trên vòng tròn bên trong. Nhìn từ trung tâm, các đỉnh nằm ở các góc cách đều nhau (góc là 2 * PI/2 * n = Pi/n). Trên một vòng tròn đơn vị (r = 1), tọa độ x, y của các điểm i = 0..n là cos (x), sin (x). Nhân các tọa độ với bán kính tương ứng (rOuter hoặc rInner, tùy thuộc vào việc tôi là lẻ hay chẵn), và thêm vectơ đó vào tâm của ngôi sao để lấy tọa độ cho mỗi đỉnh trong đường dẫn sao.

Dưới đây là các chức năng để tạo ra một hình ngôi sao với số lượng nhất định của vũ khí, trung tâm phối hợp trong và bên ngoài, bán kính bên trong:

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

Tôi nghĩ rằng bạn nên sử dụng các lớp học tương tự (GeneralPath), nhưng ở đây bạn nên tập trung vào làm thế nào để tính toán đỉnh tọa độ.

Điều đầu tiên xuất hiện trong tâm trí của tôi là định vị 2N điểm trên một vòng tròn bán kính R1, căn giữa tại (0,0). Sau đó, "strech" mỗi đỉnh lẻ bằng cách nhân vectơ của nó với c. Hằng số c phải bằng R2/R1 (tức là tỷ lệ bán kính trong và ngoài).

Nhưng có lẽ đó là một giải pháp đơn giản hơn ...

2

Dưới đây là một example tìm điểm cách đều nhau trên một circle có thể giúp. Chỉ cần thực hiện số điểm, n, một tham số trong hàm tạo.

private int n; 
... 
public CircleTest(int n) { 
    ... 
    this.n = n; 
} 
... 
for (int i = 0; i < n; i++) { 
    double t = 2 * Math.PI * i/n; 
    ... 
} 
Các vấn đề liên quan