【计算机图形学|直线生成算法】中点画线法

中点画线法是一种用于在计算机屏幕上绘制线条的算法,它基于Bresenham的对称性原理,通过计算线段斜率和控制中点位置来决定像素点的生长方向。算法通过构造判别式d和递推出增量优化,根据d值判断是选取右方或右上方像素点,从而高效地绘制线段。此方法适用于高效且精确的线性图形渲染。
摘要由CSDN通过智能技术生成

概述

中点画线法(Midpoint Line Algorithm)是一种画线(Line Drawing)算法,用来在计算机屏幕上绘制线条。

它的基本思想是从线段的起点和终点出发,按照一定的规则向终点逐步逼近,并在途中以控制变量的方式得出每个像素点的坐标,从而绘制出所需的线条。

具体实现中,中点画线法通过计算线段斜率的变化情况,来分为斜率小于1和大于等于1两种情况,并采用Bresenham的对称性原理,以中点的颜色来控制每个像素点的生长方向,从而获得较高的绘制效率和图像质量表现。

总的来说,中点画线法是一种高效且易于实现的线段绘制算法,也是计算机图形学领域最基本的算法之一。

一、基本思想

当前像素点为 ( x p , y p ) (x_p,y_p) (xp,yp),下一个像素点为 P 1 P1 P1 P 2 P2 P2
M = ( x p + 1 , y p + 0.5 ) M=(x_p+1,y_p+0.5) M=(xp+1,yp+0.5) P 1 P1 P1 P 2 P2 P2之中点, Q Q Q为理想直线与 x = x p + 1 x=x_p+1 x=xp+1垂线的交点。将 Q Q Q M M M y y y坐标进行比较。
M M M Q Q Q的下方,则 P 2 P2 P2应为下一个像素点;当 M M M Q Q Q的上方,则 P 1 P1 P1应为下一个像素点。
在这里插入图片描述

二、构造判别式:

d = F ( M ) = F ( x p + 1 , y p + 0.5 ) = a ( x p + 1 ) + b ( y p + 0.5 ) + c d=F(M)=F(x_p+1,y_p+0.5)=a(x_p+1)+b(y_p+0.5)+c d=F(M)=F(xp+1,yp+0.5)=a(xp+1)+b(yp+0.5)+c
其中, a = y 0 − y 1 , b = x 1 − x 0 , c = x 0 y 1 − x 1 y 0 a=y_0-y_1, b=x_1-x_0, c=x_0y_1-x_1y_0 a=y0y1,b=x1x0,c=x0y1x1y0.

  • d < 0 d<0 d<0时, M M M L ( Q L(Q L(Q ) ) )下方,取右上方 P 2 ( x p + 1 , y p + 1 ) P2(x_p+1,y_p+1) P2(xp+1,yp+1)为下一个像素;
  • d > 0 d>0 d>0时, M M M L ( Q L(Q L(Q ) ) )上方,取右方 P 1 ( x p + 1 , y p ) P1(x_p+1,y_p) P1(xp+1,yp)为下一个像素;
  • d = 0 d=0 d=0时,选 P 1 P1 P1 P 2 P2 P2均可,约定取 P 1 ( x p + 1 , y p ) P1(x_p+1,y_p) P1(xp+1,yp)为下一个像素;
  • 在这里插入图片描述

三、递推出增量

若当前像素处于:

d ≥ 0 d\geq 0 d0情况,则取正右方像素 P 1 ( x p + 1 , y p ) P1(x_p+1, y_p) P1(xp+1,yp),要判下一个像素位置,应计算
d 1 = F ( x p + 2 , y p + 0.5 ) = a ( x p + 2 ) + b ( y p + 0.5 ) = d + a d1=F(x_p+2, y_p+0.5)=a(x_p+2)+b(y_p+0.5)=d+a d1=F(xp+2,yp+0.5)=a(xp+2)+b(yp+0.5)=d+a
增量为 a a a

d < 0 d<0 d<0时,则取右上方像素 P 2 ( x p + 1 , y p + 1 ) P2(x_p+1, y_p+1) P2(xp+1,yp+1)。要判断再下一像素,则要计算
d 2 = F ( x p + 2 , y p + 1.5 ) = a ( x p + 2 ) + b ( y p + 1.5 ) + c = d + a + b d2= F(x_p+2, y_p+1.5)=a(x_p+2)+b(y_p+1.5)+c=d+a+b d2=F(xp+2,yp+1.5)=a(xp+2)+b(yp+1.5)+c=d+a+b
增量为 a + b a+b a+b

优化:

由于画线从 ( x 0 , y 0 (x_0, y_0 (x0,y0)开始, d d d的初值为:
d 0 = F ( x 0 + 1 , y 0 + 0.5 ) = F ( x 0 , y 0 ) + a + 0.5 b = a + 0.5 b d_0=F(x_0+1, y_0+0.5)=F(x_0, y_0)+a+0.5b=a+0.5b d0=F(x0+1,y0+0.5)=F(x0,y0)+a+0.5b=a+0.5b
可以用 2 d 2d 2d代替 d d d来避免小数,提高效率。令 d 0 = 2 a + b , d 1 = 2 a , d 2 = 2 a + 2 b d_0=2a+b, d_1=2a, d_2=2a+2b d0=2a+b,d1=2a,d2=2a+2b

总结:

如果 d > 0 d > 0 d>0,则中点 ( x , y m ) (x_, y_m) (x,ym) L ( Q ) L(Q) L(Q)的上方,此时应该取右边的像素点 P 1 ( x p + 1 , y p ) P1(x_p+1,y_p) P1(xp+1,yp),即 x x x加1、 y y y不变。此时, d d d的值增加 d 1 d1 d1,即 d = d + d 1 d=d+d1 d=d+d1

如果 d < 0 d<0 d<0,则中点 ( x m , y m ) (x_m, y_m) (xm,ym) L ( Q ) L(Q) L(Q)的下方,应该取右上方的像素点 P 2 ( x p + 1 , y p + 1 ) P2(x_p+1,y_p+1) P2(xp+1,yp+1),即 x x x y y y均加1。此时, d d d的值增加 d 2 d2 d2,即 d = d + d 2 d=d+d2 d=d+d2

四、例题分析

以P0(0,0)到P1(5,2)为例,使用中点画线法,计算 d 0 d_0 d0 d 1 d_1 d1 d 2 d_2 d2,并画出对应表格。

首先,根据两点坐标求出 a a a b b b c c c的值,有:
a = y 0 − y 1 = − 2 a=y_0-y_1=-2 a=y0y1=2
b = x 1 − x 0 = 5 b=x_1-x_0=5 b=x1x0=5
c = x 0 y 1 − x 1 y 0 = − 10 c=x_0y_1-x_1y_0=-10 c=x0y1x1y0=10

接着,根据公式得到 d 0 d_0 d0 d 1 d_1 d1 d 2 d_2 d2的初值,有:
d 0 = 2 a + b = 1 d_0 = 2a+b = 1 d0=2a+b=1
d 1 = 2 a = − 4 d_1 = 2a = -4 d1=2a=4
d 2 = 2 a + 2 b = 6 d_2 = 2a+2b = 6 d2=2a+2b=6

然后,根据中点画线法的算法流程结合总结,可以按照如下表格计算每个像素点的坐标 ( x i , y i ) (x_i,y_i) (xi,yi)以及 d i d_i di的变化:

countxydP
0001P0
110-3
2213
331-1
4425
5521P1

其中, P P P表示像素点位置, c o u n t count count表示计数, d d d表示中点到直线距离的判别式值(经过放大2倍),根据 d > 0 d>0 d>0还是 d < 0 d < 0 d<0判断所选的下一个像素点。对于 d = 0 d=0 d=0,约定选择右下方的像素点。

最终,依照算法,连线的轨迹如下:

P0 (0, 0) -> (1, 1) -> (2, 1) -> (3, 2) -> (4, 2) -> P1 (5, 2)

如下图:
在这里插入图片描述

五、伪代码

/* mid PointLine */
void Midpoint Line (int x0,int y0,int x1, int y1,int color)
     {   int a, b, d1, d2, d, x, y;
    a=y0-y1, b=x1-x0, d=2*a+b;
    d1=2*a, d2=2* (a+b);
    x=x0, y=y0;
    drawpixel(x, y, color);
    while (x<x1)
    { if (d<0)       {x++, y++, d+=d2; }
     else       {x++, d+=d1;}
     drawpixel (x, y, color);
     }  /* while */
 } 
  • 24
    点赞
  • 70
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱喝冰红茶的方舟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值