簡體   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