使用可变参数绘制星形

发布于 2024-08-30 01:58:19 字数 690 浏览 2 评论 0原文

我的任务是编写程序,允许用户绘制星星,星星的大小和手臂数量可能不同。当我处理基本星星时,我使用 GeneralPath 和点表进行操作:

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

我应该选择什么方法来绘制具有可变内半径和外半径以及不同臂数的星星?这是我应该获得的:

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

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 http://img228.imageshack.us/img228/6427/lab6c.jpg

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

总攻大人 2024-09-06 01:58:19

有 n 个臂意味着最终有 2n 个顶点,偶数顶点位于外圆,奇数顶点位于内圆。从中心看,顶点的角度均匀(角度为 2*PI/2*n = Pi/n)。在单位圆(r=1)上,点 i=0..n 的 x,y 坐标为 cos(x),sin(x)。将这些坐标乘以相应的半径(rOuter 或 rInner,取决于 i 是奇数还是偶数),并将该向量添加到星形的中心,以获得星形路径中每个顶点的坐标。

这是创建具有给定臂数、中心坐标和外半径、内半径的星形形状的函数:

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

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;
}
王权女流氓 2024-09-06 01:58:19

我认为你应该使用相同的类(GeneralPath),但在这里你应该关注如何计算顶点坐标。

我首先想到的是在以 (0,0) 为圆心、半径为 R1 的圆上放置 2N 个点。然后,通过将其向量乘以 c 来“拉伸”每个奇数顶点。常数c应等于R2/R1(即内半径和外半径的比例)。

但也许有一个更简单的解决方案......

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...

暗恋未遂 2024-09-06 01:58:19

这是上查找等距点的示例可能会有所帮助。只需将点数 n 作为构造函数中的参数即可。

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

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;
    ...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文