扫描转换算法——DDA中点画线画圆椭圆
Posted swenw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了扫描转换算法——DDA中点画线画圆椭圆相关的知识,希望对你有一定的参考价值。
我的理解:在光栅图形学中,由于每一个点的表示都只能是整数值,所以光栅图形学实际只是对对实际图形的近似表示。
数值微分法(DDA):以下PPT截图来自北京化工大学李辉老师
代码实现:
import matplotlib.pyplot as plt import matplotlib.patches as patches from pylab import * def init(ax): #将主标签设置为1的倍数 majorLocator = MultipleLocator(1); #设置主刻度标签的位置,标签文本的格式 ax.xaxis.set_major_locator(majorLocator); ax.yaxis.set_major_locator(majorLocator); ax.grid(True); if __name__ == ‘__main__‘: x0, y0, x1, y1 = map(int, input("请输入直线的起点与终点: ").split(‘ ‘)) ax = subplot(title=‘DDA‘); ax.plot([x0, x1], [y0, y1], ‘r‘); delta_x = x1-x0; delta_y = y1-y0; #画坐标轴 if x1>y1: ax.axis([x0-1, x1+1, y0-1, x1+1]); init(ax); else: ax.axis([x0-1, y1+1, y0-1, y1+1]); init(ax); #计算斜率k的值 if delta_x == 0: k = 999999999; else: k = delta_y / delta_x; #如果|k|<=1 if k>-1 and k<1: while x0<=x1: x = round(x0); y = round(y0); ax.plot(x, y, ‘b.‘); x0 += 1; y0 = y0+k; else: while y0<=y1: x = round(x0); y = round(y0); ax.plot(x, y, ‘b.‘); x0 += 1/k; y0 += 1; plt.show();
运行截图:
中点画线:以下PPT截图来自北京化工大学李辉老师
代码实现:
wimport matplotlib.pyplot as plt import matplotlib.patches as patches from pylab import * def init(ax): #将主标签设置为1的倍数 majorLocator = MultipleLocator(1); #设置主刻度标签的位置,标签文本的格式 ax.xaxis.set_major_locator(majorLocator); ax.yaxis.set_major_locator(majorLocator); ax.grid(True); if __name__ == ‘__main__‘: x0, y0, x1, y1 = map(int, input("请输入直线的起点与终点: ").split(‘ ‘)) ax = subplot(title=‘Midpoint‘); ax.plot([x0, x1], [y0, y1], ‘r‘); a = y0-y1; b = x1-x0; d = 2*a+b; d1 = 2*a; d2 = 2*(a+b); #画坐标轴 if x1>y1: ax.axis([x0-1, x1+1, y0-1, x1+1]); init(ax); else: ax.axis([x0-1, y1+1, y0-1, y1+1]); init(ax); x = x0; y = y0; ax.plot(x, y, ‘r.‘); while(x < x1): if d<0: x += 1; y += 1; d += d2; else: x += 1; d += d1; ax.plot(x, y, ‘r.‘); plt.show()
中点画圆法:以下PPT截图来自北京化工大学李辉老师
import matplotlib.pyplot as plt import matplotlib.patches as patches from pylab import * def init(ax): #将主标签设置为1的倍数 majorLocator = MultipleLocator(1); #设置主刻度标签的位置,标签文本的格式 ax.xaxis.set_major_locator(majorLocator); ax.yaxis.set_major_locator(majorLocator); ax.grid(True); if __name__ == ‘__main__‘: r = int(input("请输入半径: ")); plt.figure(figsize=(r*0.1, r*0.1)); ax = subplot(title=‘MidPointCircle‘); d = 1-r; ax.axis([-r-1, r+1, -r-1, r+1]); init(ax); x = 0; y = r; ax.plot(x, y, ‘r.‘); while(x <= y): if d<0: d += 2*x+3; else: d += 2*(x-y)+5; y -= 1; x += 1; ax.plot(x, y, ‘r.‘); ax.plot(y, x, ‘r.‘); ax.plot(x, -y, ‘r.‘); ax.plot(-y, x, ‘r.‘); ax.plot(-x, y, ‘r.‘); ax.plot(y, -x, ‘r.‘); ax.plot(-x, -y, ‘r.‘); ax.plot(-y, -x, ‘r.‘); plt.show()
椭圆的扫描转换:以下PPT截图来自北京化工大学李辉老师
代码实现:
import matplotlib.pyplot as plt import matplotlib.patches as patches import mpl_toolkits.axisartist as axisartist from pylab import * def init(ax): #设置x轴:空心箭头、数值在下方 ax.axis["x"] = ax.new_floating_axis(0, 0); ax.axis["x"].set_axisline_style("->", size = 1.0); ax.axis["x"].set_axis_direction("bottom"); #设置y轴:空心箭头、数值在右方 ax.axis["y"] = ax.new_floating_axis(1, 0); ax.axis["y"].set_axisline_style("->", size = 1.0); ax.axis["y"].set_axis_direction("right"); if __name__ == ‘__main__‘: a, b = map(int, input("请输入椭圆的长、短半径: ").split(‘ ‘)); fig = plt.figure(figsize=(5, 7)) #初始化画布 ax = axisartist.Subplot(fig, 111, title=‘MidpointElipse‘); #将绘图区对象添加到画布中 fig.add_axes(ax) init(ax); x = 0; y = b; d1 = b*b+a*a*(-b+0.25); #增量初值 ax.plot(x, y, ‘r.‘); ax.plot(x, -y, ‘r.‘); while(b*b*(x+1)<a*a*(y-0.5)): #法向量的x、y不一样大时 if d1<0: d1 += b*b*(2*x+3); x += 1; else: d1 += b*b*(2*x+3)+a*a*(-2*y+2); x += 1; y -= 1; #画四个对称点 ax.plot(x, y, ‘r.‘); ax.plot(x, -y, ‘r.‘); ax.plot(-x, y, ‘r.‘); ax.plot(-x, -y, ‘r.‘); #画到了法向量的x=y,即椭圆弧的下半部分 d2 = b*b*(x+0.5)*(x+0.5)+a*a*(y-1)*(y-1)-a*a*b*b; while y>0: #终结条件y>0 if d2<0: d2 += b*b*(2*x+2)+a*a*(-2*y+3); x += 1; y -= 1; else: d2 += a*a*(-2*y+3); y -= 1; ax.plot(x, y, ‘r.‘); ax.plot(x, -y, ‘r.‘); ax.plot(-x, y, ‘r.‘); ax.plot(-x, -y, ‘r.‘); plt.show()
以上是关于扫描转换算法——DDA中点画线画圆椭圆的主要内容,如果未能解决你的问题,请参考以下文章