掃描轉換算法——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()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM