逐點比較法直線和圓弧插補算法及實現

一年前就用逐點比較法做過直線和圓弧的插補,當時沒做筆記,現在忘光了,這次好好的整理了一番。:)

如果你看到了這裏,相信你已經對逐點比較法有所瞭解了,缺的是整個插補過程中需要用到的公式而已。

補充一點:

# 當求圓弧的正逆時,可以根據圓弧上的三個點與圓心構成的三個向量的行列式的正負來判斷,
# 如果行列式的值大於0,是逆時針,小於零,是順時針,等於零,則在一條直線上
# 這個a是圓弧的起點和圓心構成的向量, b是圓弧上中點與圓心構成的向量, c是圓弧上終點與圓心構成的向量。
def main():
    c= [0, 3, 1]
    b = [3/math.sqrt(2), 3/math.sqrt(2), 1]
    a = [3,0, 1]
    ns = a[0]*b[1]*c[2] + a[1]*b[2]*c[0] + a[2]*b[0]*c[1] - a[2]*b[1]*c[0] - a[1]*b[0]*c[2] - a[0]*b[2]*c[0]
    if ns > 0:
        print("逆時針")
    elif ns <0:
        print("順時針")
    elif ns==0:
        print("在一條直線上")
main()

 運行結果:

 

一、公式算法部分

這張圖裏的真值表是爲了在FPGA中實現直線和圓弧插補的,爲了驗證算法的正確性,我先在python做了一下仿真(因爲python簡單啊),事實證明算法沒問題,文章後面會附上完整的圓弧和直線插補的python代碼。

圓弧插補時,象限用圓弧圓心與圓弧起點的向量和圓心與圓弧終點的向量和向量(x, y)來進行判斷。在求Fm時,用到的xi, yi是當前點的座標,這個是有正負的

插補直線時,用直線終點與直線起點構成的向量的(x, y)的正負判斷象限,Fm的計算用到的座標(xe, ye)是直線終點與直線起點構成的向量的x,y座標,在求Fm時用到的是絕對值

 

二、具體實現部分

2.1直線插補:python代碼如下

import turtle

point = []


def judge_quadrant(x0, y0, xe, ye):
    x = xe - x0
    y = ye - y0
    if(x > 0) and (y > 0):  # 第一象限
        quadrant = 1
    elif(x < 0) and (y > 0):  # 第二象限
        quadrant = 2
    elif(x < 0) and (y < 0):  # 第三象限
        quadrant = 3
    elif(x > 0) and (y < 0):  # 第四象限
        quadrant = 4
    elif x > 0 and y == 0:
        quadrant = 5   # X軸正方向
    elif x < 0 and y == 0:
        quadrant = 6   # X軸負方向
    elif x == 0 and y > 0:
        quadrant = 7   # Y軸正方向
    elif x == 0 and y < 0:
        quadrant = 8   # Y軸負方向
    return quadrant


def interpolation(quadrant, x0, y0, xe, ye):
    x = xe - x0
    y = ye - y0
    fm = 0
    x1 = abs(x)
    y1 = abs(y)
    total = x1 + y1
    print("total = ",total)
    cnt = 0
    while cnt < total:
        if quadrant < 5:
            if fm >= 0:
                if quadrant == 1 or quadrant == 4:
                    x0 += 1
                elif quadrant == 2 or quadrant == 3:
                    x0 -= 1
                # point.append(p)
                fm = fm - y1
            elif fm <0:
                if quadrant == 1 or quadrant == 2:
                    y0 += 1
                elif quadrant == 3 or quadrant == 4:
                    y0 -= 1
                # point.append(p)
                fm = fm + x1
        else:
            if quadrant == 5:
                x0 += 1
            elif quadrant ==6:
                x0 -=1
            elif quadrant ==7:
                y0 += 1
            elif quadrant ==8:
                y0 -=1
        p = (x0, y0)
        point.append(p)
        cnt += 1
    print("點的列表爲:",point)


def get_points():
    line_path = [(0, 0), (-5, -6)]
    for i in range(0,len(line_path)-1):
        xo= line_path[i][0]
        yo = line_path[i][1]
        print(xo,yo)
        xe = line_path[i+1][0]
        ye = line_path[i+1][1]
        print(xe, ye)
        quadrant = judge_quadrant(xo, yo, xe, ye)
        print(quadrant)
        interpolation(quadrant,xo, yo, xe, ye)


def draw_line():
    print(point)
    turtle.goto(point[0])
    turtle.pendown()
    for item in point:
        turtle.goto(item)


def draw_coordinate():
    turtle.penup()
    turtle.goto(0,500)
    turtle.pendown()
    turtle.goto(0,-1000)
    turtle.penup()
    turtle.goto(500,0)
    turtle.pendown()
    turtle.goto(-500, 0)
    turtle.penup()
    turtle.goto(0, 0)


def main():
    draw_coordinate()
    get_points()
    draw_line()
    turtle.exitonclick()


if __name__ == '__main__':
    main()

運行效果圖:紅箭頭是路勁方向

2.2圓弧插補:python代碼

import turtle
point = []


def arc_interpolation(quadrant, sn, x1, y1, totalsteps): #sn 0:逆,1:順
    fm = 0
    point.append((x1,  y1))
    while totalsteps != 0:
        if quadrant == 1:
            if sn == 0:   #1 逆圓
                if fm >= 0:
                    fm = fm -2*x1 +1
                    x1 -= 1
                else:
                    fm = fm +2*y1 +1
                    y1 += 1
            else:   #1 順圓
                if fm >= 0:
                    fm = fm -2*y1 +1
                    y1 -= 1
                else:
                    fm = fm +2* x1 +1
                    x1 += 1
        elif quadrant == 2:
            if sn == 0:   #1 逆圓
                if fm >= 0:
                    fm = fm -2*y1 +1
                    y1 -= 1
                else:
                    fm = fm -2*x1 +1
                    x1 -= 1
            else:
                if fm >= 0:
                    fm = fm +2*x1 +1
                    x1 += 1
                else:
                    fm = fm +2*y1 +1
                    y1 += 1
        elif quadrant == 3:
            if sn==0:   #1 逆圓
                if fm >= 0:
                    fm = fm +2*x1 +1
                    x1 += 1
                else:
                    fm = fm -2*y1 +1
                    y1 -= 1
            else:
                if fm >= 0:
                    fm = fm +2*y1 +1
                    y1 += 1
                else:
                    fm = fm -2*x1 +1
                    x1 -= 1
        elif quadrant == 4:
            if sn==0:   #1 逆圓
                if fm >= 0:
                    fm = fm +2*y1 +1
                    y1 += 1
                else:
                    fm = fm +2*x1 +1
                    x1 += 1
            else:
                if fm >= 0:
                    fm = fm -2*x1 +1
                    x1 -= 1
                else:
                    fm = fm -2*y1 +1
                    y1 -= 1
        point.append((x1, y1))
        totalsteps -= 1


def judge_quadrant(xo, yo, x1, y1, x2, y2):
    x11 = x1 - xo
    y11 = y1 - yo
    x22 = x2 - xo
    y22 = y2 - yo
    x12 = x11 + x22
    y12 = y11 + y22
    if x12 > 0 and y12 > 0:
        quadrant = 1
    elif x12 < 0 and y12 > 0:
        quadrant = 2
    elif x12 < 0 and y12 < 0:
        quadrant = 3
    elif x12 > 0 and y12 < 0:
        quadrant = 4
    return quadrant


def get_points():
    line_path = [(0, 0), (-30, 0), (0, -30)]    #圓弧路徑
    sn = 0
    for i in range(0,len(line_path)-2):
        xo = line_path[i][0]
        yo = line_path[i][1]
        print(xo,yo)
        x1 = line_path[i+1][0]
        y1 = line_path[i+1][1]

        x2 = line_path[i+2][0]
        y2 = line_path[i+2][1]
        print(x1, y1,"  ", x2, y2)
        quadrant = judge_quadrant(xo, yo, x1, y1, x2, y2)
        print(quadrant)
        totalsteps = abs(x2 - x1) + abs(y2 - y1)
        arc_interpolation(quadrant, sn, x1, y1, totalsteps)


def draw_line():
    print(point)
    turtle.goto(point[0])
    turtle.pendown()
    for item in point:
        turtle.goto(item)


def draw_coordinate():
    turtle.penup()
    turtle.goto(0, 500)
    turtle.pendown()
    turtle.goto(0, -1000)
    turtle.penup()
    turtle.goto(500, 0)
    turtle.pendown()
    turtle.goto(-500, 0)
    turtle.penup()
    turtle.goto(0, 0)


def main():
    draw_coordinate()
    get_points()
    draw_line()
    turtle.exitonclick()


if __name__ == '__main__':
    main()

運行結果如下

這裏只是畫了一個圓弧,有興趣的話,可以在代碼中增加這個裏面的座標值,當然了,這個沒有實現跨象限的圓弧插補,所以,每次要畫的圓弧起點和終點須在同一象限。

line_path = [(0, 0), (-90, 0), (0, -90)]    #圓弧路徑
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章