使用可变参数绘制星形

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用可变参数绘制星形相关的知识,希望对你有一定的参考价值。

我的任务是编写允许用户绘制星星的程序,这些星星的大小和武器数量可能不同。当我处理基本的星星时,我使用的是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

答案

拥有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;
}
另一答案

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

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

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

另一答案

这是一个examplecircle上发现可能有帮助的等间距点。只需在构造函数中创建点数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;
    ...
}

以上是关于使用可变参数绘制星形的主要内容,如果未能解决你的问题,请参考以下文章

将 JSON 反序列化为具有通用字段的 Serializable 类 - 错误:不允许类型参数中的星形投影

如何绘制具有可变笔画宽度的路径

使用片段着色器在特定位置绘制完美的水平线

3D星形贴图

在c中使用递归函数的星形模式

关于Java可变参数问题?