简体   繁体   中英

Drawing tangents for a bezier curve in OpenGL using c++

So I have a program that has 4 control points

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));

Basically, what happens is that I've set up a way to move my control points and when a control point is moved, the new position is saved and the curve is re-calculated based on this new position. The way I'm drawing the curve is I'm using these equations:

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());
}

And then using these two float values, I put them into vec3's and make a bunch of points. I then draw a line between all these points by putting them into a multiline class by declaring what points will be in the curve and then drawing a straight line between each point. The end result will be a bezier curve.

The problem I'm having right now is drawing the tangents for the bezier curve. My idea was that for the first control point, was to say the tangent is on the line P1 - P2. So after drawing the tangent, when I move the tangent point, what equations am I supposed to use to re-draw the shape of the curve? I've already found the derivatives of the bezier curve equation but I don't know what to do with them:

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());

You starting tangent will be from the first control point to the second, and the ending tangent will be from the fourth control point to the third. I'd suggest you start fresh each time you redraw it; ie, whenever a control point moves, treat it as an all-new equation.

In the case that one (or both) of your tangents are zero-length, then they aren't actually tangents per se but the curve will go toward the opposite endpoint.

That's why you can use a Bezier section with no tangents to represent a straight line.

The equations are wrong.

The correct equation is

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

expand and differentiate to get the tangents.

It looks like that you want to draw the tangent points for the tangent vector at the start and end of the Bezier curve so that you can allow users to adjust the curve's shape by moving the tangent points. If this is the case, you need to be aware that moving the tangent points will also move the 2nd or the 3rd control points. So, the correct procedure would be to re-calculate the 2nd or the 3rd control point from the moved tangent points, then redraw the curve.

For cubic Bezier curve, the C'(t) at t=0 and 1 is

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

Let's assume your tangent point for the starting tangent is T0 and is located at

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

where s0 is a constant scale factor for making sure your tangent point will not be located too far away from the control points. When T0 is changed to T0*, you can update the control point P1 as

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

Do similar update for control point P2 when the tangent point of the end tangent is moved. Then, you can redraw your curve.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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