在Java中绘制贝塞尔曲线

6

我需要创建一个简单的 Java 程序,通过任意数量的点逐像素绘制贝塞尔曲线。目前,一切似乎都很好,除了曲线总是在 x=0 y=0 坐标处结束。

截图1

enter image description here

屏幕截图2

enter image description here

我需要它在最后一个点结束。我的大脑今天不太灵光,所以我需要一些帮助。
以下是我的代码:
private void drawScene(){

    precision = Float.parseFloat(this.jTextField4.getText());
    //Clears the screen and draws X and Y lines
    g.setColor(Color.white);
    g.fillRect(0, 0, pWidth, pHeight);

    g.setColor(Color.gray);
    g.drawLine(0, offsetY, pWidth, offsetY);
    g.drawLine(offsetX, 0, offsetX, pHeight);
    //Drawing the points
    if(pointCount > 0){
        for(int i = 0;i<pointCount;i++){
            g.setColor(Color.red);
            g.drawString(String.valueOf(i+1), points[i].x + offsetX, points[i].y - 6 + offsetY);
            g.drawOval(points[i].x + offsetX, points[i].y - 6 + offsetY, 3, 3);
        }
    }
    //Drawing the curve
    if(pointCount > 1){
        float t = 0;
        while(t <= 1){
            g.setColor(Color.gray);
            this.besierCurvePixel(t);
            t += precision;
        }
    }
}

//Factorial
private static int fact(int n) {
    int fact = 1;
    for (int i = 1; i <= n; i++) {
        fact *= i;
    }
    return fact;
}
//Bernstein polynomial
private static double bernstein(float t, int n, int i){

   return (fact(n) / (fact(i) * fact(n-i))) * Math.pow(1-t, n-i) * Math.pow(t, i);
}

private void besierCurvePixel(float t){

    double bPoly[] = new double[pointCount];

    for(int i = 0; i < pointCount; i++){
        bPoly[i] = bernstein(t, pointCount, i+1);
    }

    double sumX = 0;
    double sumY = 0;

    for(int i = 0; i < pointCount;  i++){
        sumX += bPoly[i] * points[i].x;
        sumY += bPoly[i] * points[i].y;
    }

    int x, y;
    x = (int) Math.round(sumX);
    y = (int) Math.round(sumY);

    g.drawLine(x + offsetX, y + offsetY, x + offsetX, y + offsetY);

}

这是添加点的方法(pointCount最初为0):

    points[pointCount] = new Point();
    points[pointCount].x = evt.getX() - this.offsetX;
    points[pointCount].y = evt.getY() - this.offsetY;
    pointCount++;

    this.drawScene();

如果您将Bernstein方法中的Math.pow(1-t, n-i)更改为Math.pow(1-t, n+1-i)会发生什么? - Rekin
1
如果您将 for(int i = 0; i < pointCount; i++){ bPoly[i] = bernstein(t, pointCount, i+1); 替换为 for(int i = 0; i <= pointCount; i++){ bPoly[i] = bernstein(t, pointCount, i);,会发生什么? - Rekin
关于边界肯定有一些错误...如果整个方程式变成零,那么要么是因为分子趋近于零,要么是因为分母趋近于无穷大。 - Rekin
2
关于使用阶乘函数的警告:使用“真实数学”计算二项式系数会非常快地出错,因为数字变得太大了。另一方面,直接构建帕斯卡三角形值要快得多/便宜得多,并且可以轻松地计算到几乎任意深度。请参考http://pomax.github.io/bezierinfo/#explanation中的“如何实现”部分。 - Mike 'Pomax' Kamermans
显示剩余3条评论
2个回答

1

问题在这里

for(int i = 0; i < pointCount; i++){
    bPoly[i] = bernstein(t, pointCount, i+1);
}

bernstein 方法的第二个参数是不正确的。基本上,如果我有 3 个点,它应该是 2 而不是 3。

bPoly[i] = bernstein(t, pointCount-1, i+1);

0

"pointcount"在哪里设置(以及设置为什么)? 您是否尝试逐步执行代码,查看为什么在到达最后一个点后它仍然继续执行? 有可能您多次循环一次,这就是为什么最后一个点的目标会设置为(0,0)吗? 您能否设置应用程序到达每个点所需的步数?

希望我提出的观点能帮助您找到答案。

*编辑:如果我猜测的话-您不小心将另一个(0,0)点添加到points[]中;这就是我在最后一个点之后看到它转到(0,0)的地方:

for(int i = 0; i < pointCount;  i++){
    sumX += bPoly[i] * **points[i]**.x;
    sumY += bPoly[i] * **points[i]**.y;
}

编辑:很高兴您能解决问题,希望我能帮助找到问题。祝您未来顺利!


我使用System.out.println(Arrays.toString(points));检查了points对象,似乎并没有多余的点。 - Rai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接