繁体   English   中英

使用C ++在OpenGL中绘制贝塞尔曲线的切线

[英]Drawing tangents for a bezier curve in OpenGL using c++

所以我有一个有4个控制点的程序

std::vector<ControlPoint> cam_pos_points;
    cam_pos_points.push_back(ControlPoint(-0.79, 0.09, 0.2, 0));
    cam_pos_points.push_back(ControlPoint(-0.88, -0.71, 0.2, 1));
    cam_pos_points.push_back(ControlPoint(1.3, -0.8, 0.2, 2));
    cam_pos_points.push_back(ControlPoint(0.71, 0.76, 0.2, 3));

基本上,发生的事情是我已经建立了一种移动控制点的方法,并且当移动控制点时,将保存新位置,并根据该新位置重新计算曲线。 我绘制曲线的方式是使用以下等式:

for (double t = 0; t < 1; t += 0.1){
    float Px =(pow((1 - t), 3) * cam_pos_points[0].positionx()) + 
        ((pow((1 - t), 2) * t) * cam_pos_points[1].positionx()) + 
        (((1 - t) * pow(t, 2)) * cam_pos_points[2].positionx()) + 
        (pow(t, 3) * cam_pos_points[3].positionx());

    float Py =(pow((1 - t), 3) * cam_pos_points[0].positiony()) + 
        ((pow((1 - t), 2) * t) * cam_pos_points[1].positiony()) + 
        (((1 - t) * pow(t, 2)) * cam_pos_points[2].positiony()) + 
        (pow(t, 3) * cam_pos_points[3].positiony());
}

然后使用这两个浮点值,将它们放入vec3中并得出一堆点。 然后,通过声明曲线中将要包含哪些点,然后在每个点之间绘制一条直线,将它们置于多线类中,从而在所有这些点之间绘制一条线。 最终结果将是贝塞尔曲线。

我现在遇到的问题是绘制贝塞尔曲线的切线。 我的想法是,对于第一个控制点,就是说切线在P1-P2线上。 因此,在绘制切线之后,当我移动切线点时,应该使用什么方程式重新绘制曲线的形状? 我已经找到了贝塞尔曲线方程的导数,但是我不知道该如何处理它们:

float dx = (-3*(pow((1 - t), 2)) * cam_pos_points[0].positionx()) + 
             (((-2*(1 - t)) * t) * cam_pos_points[1].positionx()) + 
              (((1 - t) * (2*t)) * cam_pos_points[2].positionx()) + 
                  ((3*pow(t, 2)) * cam_pos_points[3].positionx());

float dy = (-3*(pow((1 - t), 2)) * cam_pos_points[0].positiony()) + 
             (((-2*(1 - t)) * t) * cam_pos_points[1].positiony()) + 
              (((1 - t) * (2*t)) * cam_pos_points[2].positiony()) + 
                  ((3*pow(t, 2)) * cam_pos_points[3].positiony());

您的起始切线将从第一个控制点到第二个控制点,结束切线将从第四个控制点到第三个控制点。 我建议您每次重画时都要重新开始。 即,只要控制点移动,就将其视为全新方程式。

如果您的一个切线(或两个切线)的长度均为零,那么它们本身实际上并不是切线但曲线将朝相反的端点。

这就是为什么您可以使用没有切线的Bezier截面来代表直线的原因。

方程是错误的。

正确的方程是

(1-t)^3 * p0 + 3*(1-t)^2*t * p1 + 3*(1-t)*t^2 * p2 + t^3 * p3. 

扩展和区分以获得切线。

看起来您想在Bezier曲线的起点和终点绘制切线向量的切点,以便您可以允许用户通过移动切线点来调整曲线的形状。 在这种情况下,您需要注意,移动切线点也会移动第二个或第三个控制点。 因此,正确的过程将是从移动的切点重新计算第二个或第三个控制点,然后重新绘制曲线。

对于三次贝塞尔曲线,在t = 0和1处的C'(t)为

C'(0)= 3 *(P1-P0)
C'(1)= 3 *(P3-P2)

假设起始切线的切线点为T0且位于

T0 = P0 + s0 * C'(0)= P0 + 3 * s0 *(P1-P0)

其中s0是恒定比例因子,用于确保切线点不会离控制点太远。 当T0更改为T0 *时,可以将控制点P1更新为

P1 * =(T0 * -P0)/(3 * s0)+ P0。

当末端切线的切点移动时,对控制点P2进行类似的更新。 然后,您可以重绘曲线。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM