圆锥曲线绘制
二次曲线:
\[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)\)。
![image-20211122114630254](https://tva1.sinaimg.cn/large/008i3skNly1gwns6rj6jvj30e609oglm.jpg)
令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\)。
![截屏2021-11-22 上午11.51.45](https://tva1.sinaimg.cn/large/008i3skNly1gwnscama2gj310w0u0gp5.jpg)
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 椭圆的扫描转换算法
![截屏2021-11-22 下午2.56.14](https://tva1.sinaimg.cn/large/008i3skNly1gwnxo7tgqaj319u0u0ad9.jpg)
![截屏2021-11-22 下午4.33.57](https://tva1.sinaimg.cn/large/008i3skNly1gwo0hvbqjtj310z0u00xk.jpg)
![截屏2021-11-22 下午4.35.36](https://tva1.sinaimg.cn/large/008i3skNly1gwo0jmeyfrj31bq0u00wj.jpg)
![截屏2021-11-22 下午4.36.16](https://tva1.sinaimg.cn/large/008i3skNly1gwo0ka9oizj31cb0u0439.jpg)
---- suffer now and live the rest of your life as a champion ----