我的理解:在光柵圖形學中,由於每一個點的表示都只能是整數值,所以光柵圖形學實際只是對對實際圖形的近似表示。
數值微分法(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()