科赫雪花实施中的小虫子

时间:2013-10-02 06:51:26

标签: java math fractals

所以我正在编写一个递归程序,该程序应该使用OpenGL绘制Koch的雪花,并且除了一个小问题之外,我已经完成了该程序。递归越深,奇怪的2特定顶点得到。图片底部。

编辑:我真的不关心OpenGL方面,我已经把那部分放下了。如果你不知道OpenGL,那么glVertex所做的就是在2个方法调用中指定的两个顶点之间画一条线。假装它的drawLine(v1,v2)。相同的差异。

我怀疑我找到积分的方法是罪魁祸首,但我找不到任何看起来不正确的东西。

我遵循基本标准的绘图方法,这里是相关的代码剪辑

(V代表顶点V1是左下角,v2是右下角,v3是顶角):

        double dir = Math.PI;
        recurse(V2,V1,n);

        dir=Math.PI/3;
        recurse(V1,V3,n);

        dir= (5./3.)* Math.PI ;
        recurse(V3,V2,n);

递归方法:

public void recurse(Point2D v1, Point2D v2, int n){
    double newLength = v1.distance(v2)/3.;
    if(n == 0){
        gl.glVertex2d(v1.getX(),v1.getY());
        gl.glVertex2d(v2.getX(),v2.getY());

    }else{

        Point2D p1 = getPointViaRotation(v1, dir, newLength);
        recurse(v1,p1,n-1);
        dir+=(Math.PI/3.);

        Point2D p2 = getPointViaRotation(p1,dir,newLength);
        recurse(p1,p2,n-1);
        dir-=(Math.PI*(2./3.));

        Point2D p3 = getPointViaRotation(p2, dir, newLength);
        recurse(p2,p3,n-1);
        dir+=(Math.PI/3.);

        recurse(p3,v2,n-1);
    }

}

我真的怀疑我的数学是问题所在,但这对我来说是正确的:

public static Point2D getPointViaRotation(Point2D p1, double rotation, double length){
    double xLength = length * Math.cos(rotation);
    double yLength = length * Math.sin(rotation);
    return new Point2D.Double(xLength + p1.getX(), yLength + p1.getY());
}

N = 0(一切顺利):

enter image description here

N = 1(也许有点弯曲,也许)

enter image description here

N = 5(WAT)

enter image description here

3 个答案:

答案 0 :(得分:4)

我无法在代码方面看到任何明显的问题。然而,我确实有一个关于会发生什么的理论。

图中的所有点似乎都是基于之前点的位置。因此,在此过程中发生的任何舍入错误最终都会开始累积,最终会以乱七八糟的方式结束并离开。

我会为初学者做的是在递归之前计算每个片段的起点和终点,以限制内部调用的舍入误差的影响。

答案 1 :(得分:2)

关于Koch雪花的一件事是,该算法将导致一次舍入问题(它是递归的并且所有舍入误差加起来)。诀窍是,尽可能长时间地保持它。你可以做三件事:

  • 如果您想要更详细,唯一的方法是扩展Double的可能性。您需要使用自己的坐标范围,并在每次实际在屏幕上绘制时将其转换为屏幕坐标。您自己的坐标应缩放并显示例如协调系统中的最后一个递归步骤(最后一个三角形)。 100×100。然后在其上计算三个新三角形,转换为屏幕坐标并绘制。
  • dir=Math.PI/3;行除以3而不是(double) 3。在.
  • 之后添加3
  • 确保在任何地方使用Point2D.Double。你的代码应该这样做,但我会在任何地方明确地写它。

你赢了比赛,当你还有一个漂亮的雪花但得到一个Stackoverflow

答案 2 :(得分:1)

所以,事实证明我是最愚蠢的人。

感谢大家的努力,感谢您的帮助。

此代码用于处理等边三角形,它非常具体(可以从角度看)。

我放入一个高度等于底座的三角形(不是等边的)。当我修改输入三角形时,一切都很好。