计算机图形学几种直线生成算法

 

计算机图形学几种直线生成算法

计算机图形学几种直线生成算法

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *

windowHeight=400
windowWidth=400

#自己封装了一个根据像素坐标对应到opengl的方法
def setPixel(x,y):
    glVertex(x*2/windowWidth,y*2/windowHeight)

#openGL自带算法
def DrawLine1(x1,y1,x2,y2):
    glBegin(GL_LINES)
    setPixel(x1,y1)
    setPixel(x2,y2)
    glEnd()

#DDA数值微分算法
#其中m与y为float,其他为int
def DrawLine2(x1,y1,x2,y2):
    glBegin(GL_POINTS)
    if x1>x2:
        x1,y1,x2,y2=x2,y2,x1,y1
    y=y1
    #斜率无穷的异常
    if x1==x2:
        if y1>y2:
            y1,y2=y2,y1
        for Ay in range(y1,y2):
            setPixel(x1,Ay)
        glEnd()
        return
    m=(y2-y1)/(x2-x1)
    for x in range(x1,x2+1):
        setPixel(x,y)
        y+=m
    glEnd()
##    print("x={},y={}".format(x,y))
##    print(type(x1))
##    print(type(y1))
##    print(type(x2))
##    print(type(y2))
##    print(type(x))
##    print(type(y))
##    print(type(m))

#逐点比较法
def DrawLine3(x1,y1,x2,y2):
    glBegin(GL_POINTS)
    if y1>=y2:
        yA,xA=y1-y2,x1-x2
    else:
        yA,xA=y2-y1,x2-x1
    n=abs(yA)+abs(xA)
    x=y=0
    F=y*xA-x*yA
    if xA>0:
        for i in range(0,n):
            if F>0:
                x+=1
                F=F-yA
            else:
                y+=1
                F=F+xA
            if y1<y2:
                setPixel(x+x1,y+y1)
            else:
                setPixel(x+x2,y+y2)
    else:
        for i in range(0,n):
            if F>0:
                y+=1
                F=F+xA
            else:
                x-=1
                F=F+yA
            if y1>=y2:
                setPixel(x+x2,y+y2)
            else:
                setPixel(x+x1,y+y1)
    glEnd()
##    print(type(x1))
##    print(type(y1))
##    print(type(x2))
##    print(type(y2))
##    print(type(x))
##    print(type(y))
##    print(type(xA))
##    print(type(yA))
##    print(type(n))
##    print(type(F))

#Bresenham画线法
def DrawLine4(x1,y1,x2,y2):
    glBegin(GL_POINTS)
    dx=abs(x2-x1)
    dy=abs(y2-y1)
    #将斜率变化到0,1
    flag=0
    if dy>dx:
        flag=1
        x1,y1=y1,x1
        x2,y2=y2,x2
        dx,dy=dy,dx
    #拓展象限
    tx=1 if x2>x1 else -1
    ty=1 if y2>y1 else -1
    #判别式初值
    d=2*dy-dx
    x,y=x1,y1
    #判别式递推
    while x != x2:
        if d>=0:
            y+=ty
            d+=2*(dy-dx)
        else:
            d+=2*dy
        x+=tx
        if flag:
            setPixel(y,x)
        else:
            setPixel(x,y)
    glEnd()
##    print(type(x1))
##    print(type(y1))
##    print(type(x2))
##    print(type(y2))
##    print(type(dx))
##    print(type(dy))
##    print(type(flag))
##    print(type(tx))
##    print(type(ty))
##    print(type(d))

#中点画线法
def DrawLine5(x1,y1,x2,y2):
    glBegin(GL_POINTS)
    flag=0
    if abs(x2-x1)<abs(y2-y1):
        flag=1
        x1,y1=y1,x1
        x2,y2=y2,x2
    if x1>x2:
        x1,x2=x2,x1
        y1,y2=y2,y1
    a=(y1-y2)*2
    b=(x2-x1)*2
    d=a+b//2
    if y1<=y2:
        x,y=x1,y1
        while x!=x2:
            if d<0:
                d+=a+b
                y+=1
            else:
                d+=a
            x+=1
            if flag:
                setPixel(y,x)
            else:
                setPixel(x,y)
    else:
        x,y=x2,y2
        while x!=x1:
            if d<0:
                d+=-a+b
                y+=1
            else:
                d+=-a
            x-=1
            if flag:
                setPixel(y,x)
            else:
                setPixel(x,y)
    glEnd()
##    print(type(x1))
##    print(type(y1))
##    print(type(x2))
##    print(type(y2))
##    print(type(flag))
##    print(type(a))
##    print(type(b))
##    print(type(d))
##    print(type(x))
##    print(type(y))
    
def Draw():
    #效果比较
    DrawLine1(-160,-100,160,180)
    DrawLine2(-160,-120,160,160)
    DrawLine3(-160,-140,160,140)
    DrawLine4(-160,-160,160,120)
    DrawLine5(-160,-180,160,100)

    #8个方向的绘制测试
##    DrawLine5(-50,100,50,-100)
##    DrawLine5(0,100,0,-100)
##    DrawLine5(50,100,-50,-100)
##    DrawLine5(100,100,-100,-100)
##    DrawLine5(100,50,-100,-50)
##    DrawLine5(100,0,-100,0)
##    DrawLine5(100,-50,-100,50)
##    DrawLine5(100,-100,-100,100)
    
    glFlush()
 
glutInit()
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA)
glutInitWindowSize(windowWidth, windowHeight)
glutCreateWindow("Line")
glutDisplayFunc(Draw)
glutMainLoop()