【发布时间】:2017-06-12 17:54:39
【问题描述】:
所以我有一个有 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());
【问题讨论】:
-
为什么使用
pow而不是直接计算?float mt = 1-t, t2 = t*t, mt2 = mt * mt, t3 = t2*t, mt3=mt2*mt;然后使用它们。削减一些开销。在那张纸条上:我不知道你在计算什么,但这不是贝塞尔曲线。三次贝塞尔曲线采用a * (t-1)^3 + b * 3 * t * (t-1)^2 + c * 3 * (t-1) * t^2 + d * t^3的形式,其中 a、b、c 和 d 是您的坐标。前往pomax.github.io/bezierinfo/#control 并通读前几节以确保您的数学是正确的。现在:你还没有。
标签: c++ opengl point bezier curve