1. 程式人生 > 其它 >圓錐曲線繪製

圓錐曲線繪製

二次曲線:

\[Ax^2+Bxy+cy^2+Dx+Ey+F=0 \]

可以表示圓弧,橢圓,拋物線。它們的繪製是使用離散的小直線段來逼近理想曲線。

1 繪製整圓的Bresenham演算法

  • 八路對稱
  • 只計算 45度至90度範圍內的點
  • 移動方向為+x,-y

當前畫的點為\(P(x_i, y_i)\), 下一個點可以是 \(T(x_i+1,y_i)\)\(S(x_i+1,y_i-1)\)

D(T)為T點到原點距離的平方與半徑的平方之差,D(S)為S點到原點距離與半徑平方之差

則:

\[D(T)=(x_i+1)^2 + (y_i)^2 - r^2 \\ D(S)=(x_i+1)^2 + (y_i-1)^2 - r^2 \]

因為 D(T) > 0, D(S) < 0,令變數 \(d_i= D(T) + D(S)\)

則:

\[d_i = 2(x_i+1)^2 + y_i^2 + (y_i-1)^2 - 2r^2 \]

\(d_i<0\), 有 \(|D(T)| < |D(S)|\), 選擇畫素 \(T\)。否則選擇畫素 \(S\)

2 角度離散法繪製圓弧和橢圓弧

input:圓心座標\((x_c, y_c)\) 半徑 \(r\),則以角度 \(t\) 為引數的圓的引數方程為:

\[x = x_c + r\cos t y = y_c + r\sin t \]
  • 藉助引數方程繪製曲線的方法都是將圓弧離散化為短直線段,該方法的好處是:無需處理孤立的畫素點,而是轉化為直線繪製演算法來控制
void Arc(int xc, int yc, double r, double ts, double te){
  double pi = 3.1415926;
  if (te < ts){
    te += 2 * pi;
  }
  
  double dt = 0.4 / r; // 角度的離散值, 使其與半徑成反比
  int n = (int)( (te-ts)/dt + 0.5 ); // 確定總步數, 0.5 是四捨五入
  double ta = ts;
  int x = xc + int(r * cos(ts));
  int y = yc + int(r * sin(ts));
  
  MoveTo(x, y); // 畫筆移到初始點 (x,y) 處
  for(int i = 1; i <= n; ++i){
    ta += dt;
    double cost = cos(ta);
    double sint = sin(ta);
    x = int(xc + r * cost);
    y = int(yc + r * sint);
    LineTo(x, y); // 當前畫筆位置與 (x,y) 連一條線, 然後將畫筆位置移動到 (x,y)
  }
  
}

3 橢圓的掃描轉換演算法

---- suffer now and live the rest of your life as a champion ----