Bezier曲线的OpenGL坐标

5 opengl bezier coordinates

基本上,我需要从OpenGL中的Bezier曲线实现中获取所有坐标.具体来说,我需要坐标沿着弯曲的轨迹路径在我的场景中移动球体对象(棒球).这就是我用来绘制曲线的方法:

GL2 gl = drawable.getGL().getGL2();    
float ctrlpoints[][] = new float[][]{
            {0.0f, 0.0f, 60f},
            {0.0f, 3.0f, 45.0f},
            {0.0f, 2.0f, 15.0f},
            {0.0f, 1.0f, 0f}};
    FloatBuffer ctrlpointBuf = FloatBuffer.allocate(ctrlpoints[0].length * ctrlpoints.length);
        for (int i = 0; i < ctrlpoints.length; i++) {
            for (int j = 0; j < 3; j++) {
                ctrlpointBuf.put(ctrlpoints[i][j]);
            }
        }
        ctrlpointBuf.rewind();

        gl.glMap1f(GL2.GL_MAP1_VERTEX_3, 0.0f, 1.0f, 3, numControlPoints, ctrlpointBuf);
        gl.glEnable(GL2.GL_MAP1_VERTEX_3);

        gl.glColor3f(1.0f, 1.0f, 1.0f);
        gl.glBegin(GL2.GL_LINE_STRIP);
        for (int i = 0; i <= 30; i++) {
            gl.glEvalCoord1f((float) i / (float) 30.0);
        }
        gl.glEnd();
Run Code Online (Sandbox Code Playgroud)

有没有人知道如何从这个实现中获得积分?

650*_*502 22

贝塞尔曲线非常容易计算.首先是可分离的,这意味着你可以一次计算一个坐标(先是x,然后是y,然后是z ......).对于给定的坐标,以下是使用定义的函数:

double bezier(double A,  // Start value
              double B,  // First control value
              double C,  // Second control value
              double D,  // Ending value
              double t)  // Parameter 0 <= t <= 1
{
    double s = 1 - t;
    double AB = A*s + B*t;
    double BC = B*s + C*t;
    double CD = C*s + D*t;
    double ABC = AB*s + BC*t;
    double BCD = BC*s + CD*t;
    return ABC*s + BCD*t;
}
Run Code Online (Sandbox Code Playgroud)

请注意,在上面的函数中,参数t不是曲线的弧长参数,而是从t=0(曲线的起点处)到t=1(曲线的末尾处)的通用参数.

对于t = 0.35,评估Bezier立方

上面的图片的互动版,您可以拖动A,B,C,d和AB点可以在这里找到.它使用html/js/canvas实现,仅在Chrome,Firefox,Safari上进行测试.

如果需要在XYZ中以受控的特定速度移动对象,则可以轻松计算近似折线(例如,通过对100个值的曲线进行采样t),然后在生成的折线上以恒定速度行走.

Bezier立方体的真正弧长参数化(即使用沿曲线测量的长度的参数)计算起来相当烦人(IIRC没有用于积分的闭合形式解).

  • 您可以构建一个近似折线,例如每0.01评估一次,然后以您需要的速度在折线上行走.这很简单,基本上与正确但数学上烦人的弧长参数化无法区分. (2认同)