扫描转换算法——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中点画线画圆椭圆的主要内容,如果未能解决你的问题,请参考以下文章

直线扫描算法(个人总结,仅供参考)

计算机图形学:直线段扫描转换算法

计算机图形学中的中点画线,中点画圆,Bresenham画线与画圆算法

中点画线法画圆

OpenGL实现DDA画线算法

求计算机图形学中的直线绘制函数法、DDA算法、中点法和Bresenham算法的优缺点以及比较.