图形学 画线算法

0.原始

y = k x + b y=kx+b y=kx+b
k = y 1 − y 0 x 1 − x 0 k=\frac{y_1-y_0}{x_1-x_0} k=x1x0y1y0
假 设 x 已 知 , 即 从 x 的 起 点 x 0 开 始 , 沿 x 方 向 前 进 一 个 像 素 ( 步 长 等 于 1 ) , 可 以 计 算 出 对 应 的 y 值 假设x已知,即从x的起点x_0开始,沿x方向前进一个像素(步长等于1),可以计算出对应的y值 xxx0沿x1y
由于像素的坐标是整数,所以y值还要进行取整处理

直接向下取整误差大: p ( 1.7 , 0.8 ) → 取 整 p ( 1 , 0 ) p(1.7,0.8)\overset{取整}{\rightarrow}p(1,0) p(1.7,0.8)p(1,0)

四舍五入取整误差小: p ( 1.7 , 0.8 ) → + 0.5 p ( 2..2 , 1.3 ) → + 0.5 p ( 2 , 1 ) p(1.7,0.8)\overset{+0.5}{\rightarrow}p(2..2,1.3)\overset{+0.5}{\rightarrow}p(2,1) p(1.7,0.8)+0.5p(2..2,1.3)+0.5p(2,1)

1.数值微分法(DDA )画线法

使用增量思想,将乘法减少,只剩下加法
y i = k x i + b y_i=kx_i+b yi=kxi+b

y i + 1 = k x i + 1 + b y_{i+1}=kx_{i+1}+b yi+1=kxi+1+b
y i + 1 = k ( x 1 + 1 ) + b y_{i+1}=k(x_1+1)+b yi+1=k(x1+1)+b
y i + 1 = k x 1 + b + k y_{i+1}=kx_1+b+k yi+1=kx1+b+k
y i + 1 = y 1 + k y_{i+1}=y_1+k yi+1=y1+k
当前的y值等于前一步的y值加上斜率k
斜率小于等于0时,可以使用y方向,如果斜率大于1,则需要使用x方向递增,否则会出现距离很大的离散点

2.中点画线法

改进效率,将浮点运算变为整数加法
F ( x , y ) = A x + B y + C = 0 F(x,y)=Ax+By+C=0 F(x,y)=Ax+By+C=0

  • 对 于 直 线 上 的 点 F ( x , y ) = 0 对于直线上的点 F(x,y)=0 线F(x,y)=0
  • 对 于 直 线 上 方 的 点 F ( x , y ) > 0 对于直线上方的点 F(x,y)>0 线F(x,y)>0
  • 对 于 直 线 下 方 的 点 F ( x , y ) < 0 对于直线下方的点 F(x,y)<0 线F(x,y)<0

假定: 0 ≤ ∣ k ∣ ≤ 1 0 \leq |k| \leq1 0k1。因此,每次x方向上加1,y方向上加1或不变需要判断

y 方 向 上 y i 与 y i + 1 的 中 点 为 y m y方向上y_i与y_{i+1}的中点为y_m yyiyi+1ym
d i = F ( x m , y m ) d_i=F(x_m,y_m) di=F(xm,ym)
d i = A x m + B y m + C d_i=Ax_m+By_m+C di=Axm+Bym+C
d i = A ( x i + 1 ) + B ( y i + 0.5 ) + C d_i=A(x_i+1)+B(y_i+0.5)+C di=A(xi+1)+B(yi+0.5)+C

  • 当 d < 0 时 : 中 点 在 下 方 , 说 明 应 取 上 方 的 点 当d<0时:中点在下方,说明应取上方的点 d<0
  • 当 d > 0 时 : 中 点 在 上 方 , 说 明 应 取 下 方 的 点 当d>0时:中点在上方,说明应取下方的点 d>0

引进增量思想
y = { y + 1 ( d < 0 ) y ( d ≥ 0 ) y=\left\{\begin{matrix} & y+1 &(d<0) \\ & y &(d\geq0) \end{matrix}\right. y={y+1y(d<0)(d0)

d 0 = F ( x m 0 , y m 0 ) d_0=F(x_{m_0},y_{m_0}) d0=F(xm0,ym0)
d 0 = F ( x 0 + 1 , y 0 + 0.5 ) d_0=F(x_0+1,y_0+0.5) d0=F(x0+1,y0+0.5)
d 0 = A ( x 0 + 1 ) + B ( y 0 + 0.5 ) + C d_0=A(x_0+1)+B(y_0+0.5)+C d0=A(x0+1)+B(y0+0.5)+C
d 0 = A x 0 + B y 0 + C + A + 0.5 B d_0=Ax_0+By_0+C+A+0.5B d0=Ax0+By0+C+A+0.5B由于原点在直线上,
d 0 = A + 0.5 B d_0=A+0.5B d0=A+0.5B

当 d < 0 时 当d<0时 d<0
d 1 = F ( x m 1 , y m 1 ) d_1=F(x_{m_1},y_{m_1}) d1=F(xm1,ym1)
d 1 = F ( x i + 2 , y i + 1.5 ) d_1=F(x_i+2,y_i+1.5) d1=F(xi+2,yi+1.5)
d 1 = A ( x i + 2 ) + B ( y i + 1.5 ) + C d_1=A(x_i+2)+B(y_i+1.5)+C d1=A(xi+2)+B(yi+1.5)+C
d 1 = A ( x i + 1 ) + B ( y i + 0.5 ) + C + A + B d_1=A(x_i+1)+B(y_i+0.5)+C+A+B d1=A(xi+1)+B(yi+0.5)+C+A+B
d 1 = d 0 + A + B d_1=d_0+A+B d1=d0+A+B

当 d ≥ 0 时 当d\geq0时 d0
d 1 = F ( x m 1 , y m 1 ) d_1=F(x_{m_1},y_{m_1}) d1=F(xm1,ym1)
d 1 = F ( x i + 2 , y i + 1.5 ) d_1=F(x_i+2,y_i+1.5) d1=F(xi+2,yi+1.5)
d 1 = A ( x i + 2 ) + B ( y i + 0.5 ) + C d_1=A(x_i+2)+B(y_i+0.5)+C d1=A(xi+2)+B(yi+0.5)+C
d 1 = A ( x i + 1 ) + B ( y i + 0.5 ) + C + A d_1=A(x_i+1)+B(y_i+0.5)+C+A d1=A(xi+1)+B(yi+0.5)+C+A
d 1 = d 0 + A d_1=d_0+A d1=d0+A

d n e w = { d o l d + A + B ( d o l d < 0 ) d o l d + A ( d o l d ≥ 0 ) d_{new}=\left\{\begin{matrix} & d_{old}+A+B &(d_{old}<0) \\ & d_{old}+A &(d_{old}\geq0) \end{matrix}\right. dnew={dold+A+Bdold+A(dold<0)(dold0)
d 0 = A + 0.5 B d_0=A+0.5B d0=A+0.5B
A、B、C作为整数,则我们将2d代入,可以将浮点运算减去

3.Bresenham 画线法

算法不仅可以解决画直线问题,还能解决圆弧、抛物线甚至只有曲线的光栅化问题

思想是通过各行、各列像素中心构造一组虚拟网格线,按照直线七点到终点的顺序,计算直线与各垂直网格线的交点,然后根据误差项的符号确定该列像素中与交点最近的像素。

假设每次x+1,y的递增(减)量为0或者1,它取决于实际直线与最近光栅网格点的距离,这个距离的最大误差为0.5。

k为斜率
d = d + k d=d+k d=d+k
一旦 d ≥ 1 , 就 把 它 减 去 1 , 保 证 d 的 相 对 性 , 且 在 0 、 1 之 间 d\geq1,就把它减去1,保证d的相对性,且在0、1之间 d11d01

{ x i + 1 = x i + 1 y i + 1 = { y i + 1 = y i + 1 ( d > 0.5 ) y i ( d ≤ 0.5 ) \left\{\begin{matrix} & x_{i+1}=x_i+1 &\\ & y_{i+1}=\left\{\begin{matrix} & y_{i+1}=y_i+1 &(d>0.5) \\ & y_{i} &(d\leq0.5) \end{matrix}\right. & \end{matrix}\right. xi+1=xi+1yi+1={yi+1=yi+1yi(d>0.5)(d0.5)

令e=d-0.5
{ x i + 1 = x i + 1 y i + 1 = { y i + 1 = y i + 1 ( e > 0 ) y i ( e ≤ 0 ) \left\{\begin{matrix} & x_{i+1}=x_i+1 & \\ & y_{i+1}=\left\{\begin{matrix} & y_{i+1}=y_i+1 &(e>0) \\ & y_{i} &(e\leq0) \end{matrix}\right. & \end{matrix}\right. xi+1=xi+1yi+1={yi+1=yi+1yi(e>0)(e0)

e>0,y方向递增1;e<0,y方向不递增
e=0时,可任选上下光栅点显示

  • e 0 = − 0.5 e_0=-0.5 e0=0.5
  • 每走一步有e=e+k
  • 如果e>0则e=e-1

由于算法中只用到误差项的符号,所以可以使用 e ∗ 2 ∗ △ x e*2* \bigtriangleup x e2x来替换e

k = d y d x k=\frac{dy}{dx} k=dxdy

  • e 0 = − △ x e_0=- \bigtriangleup x e0=x
  • 每 走 一 步 有 e = e + 2 ∗ △ y 每走一步有e=e+2* \bigtriangleup y e=e+2y
  • 如 果 e > 0 则 e = e − 2 ∗ △ x 如果e>0则e=e-2* \bigtriangleup x e>0e=e2x
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值