1. 程式人生 > >基於FPGA的逐點比較法直線和圓弧插補演算法及實現

基於FPGA的逐點比較法直線和圓弧插補演算法及實現

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

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

補充一點:

# 當求圓弧的正逆時,可以根據圓弧上的三個點與圓心構成的三個向量的行列式的正負來判斷,
# 如果行列式的值大於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)]    #圓弧路徑