【问题标题】:offset a parallel line to a given line python将平行线偏移到给定线python
【发布时间】:2021-06-23 17:56:45
【问题描述】:

我想绘制平行线到给定的 X,Y 坐标下面的代码有助于绘制,

import numpy as np
import matplotlib.pyplot as plt

x = [187, 879, 722, 322]

y = [341, 344, 112, 112]


newX = []
newY = []

def findIntesection(p1x, p1y, p2x, p2y, p3x,p3y, p4x, p4y):
    dx12 = p2x - p1x
    dy12 = p2y - p1y
    dx34 = p4x - p3x
    dy34 = p4y - p3y

    denominator = (dy12*dx34-dx12*dy34)

    t1 = ((p1x - p3x) * dy34 + (p3y - p1y) * dx34)/ denominator

    t2 = ((p3x - p1x) * dy12 + (p1y - p3y) * dx12)/ -denominator;
    
    intersectX = p1x + dx12 * t1
    intersectY = p1y + dy12 * t1

    if (t1 < 0): t1 = 0
    elif (t1 > 1): t1 = 1
    if (t2 < 0): t2 = 0
    elif (t2 > 1): t2 = 1
    
    return intersectX,intersectY

def normalizeVec(x,y):
    distance = np.sqrt(x*x+y*y)
    return x/distance, y/distance

def getEnlarged(oldX, oldY, offset):
    num_points = len(oldX)
    
    for j in range(num_points):
        i = j - 1
        if i < 0:
            i += num_points
        k = (j + 1) % num_points

        vec1X =  oldX[j] - oldX[i]
        vec1Y =  oldY[j] - oldY[i]
        v1normX, v1normY = normalizeVec(vec1X,vec1Y)
        v1normX *= offset
        v1normY *= offset
        n1X = -v1normY
        n1Y = v1normX
        pij1X = oldX[i] + n1X
        pij1Y = oldY[i] + n1Y
        pij2X = oldX[j] + n1X
        pij2Y = oldY[j] + n1Y

        vec2X =  oldX[k] - oldX[j]
        vec2Y =  oldY[k] - oldY[j]
        v2normX, v2normY = normalizeVec(vec2X,vec2Y)
        v2normX *= offset
        v2normY *= offset
        n2X = -v2normY
        n2Y = v2normX
        pjk1X = oldX[j] + n2X
        pjk1Y = oldY[j] + n2Y
        pjk2X = oldX[k] + n2X
        pjk2Y = oldY[k] + n2Y
        
        intersectX,intersetY = findIntesection(pij1X,pij1Y,pij2X,pij2Y,pjk1X,pjk1Y,pjk2X,pjk2Y)
        
        #print(intersectX,intersetY)
        
        newX.append(intersectX)
        newY.append(intersetY)

getEnlarged(x, y, 20)

plt.plot(x, y)
plt.plot(newX, newY)
plt.show()

结果如下

在这里,通过为梯形的每条线绘制平行线可以得到很好的结果,但我希望它是封闭的形状而不是开放的形状 我想加入第一个和最后一个坐标,使其形成一个封闭的形状。任何帮助将不胜感激。

【问题讨论】:

    标签: python matplotlib math geometry computational-geometry


    【解决方案1】:

    使用来自here的方法

    outer_ccw 参数结合了顶点顺序和所需的偏移方向。 CCW 顺序和外多边形为 1,内多边形应为 -1。

    def makeOffsetPoly(oldX, oldY, offset, outer_ccw = 1):
        num_points = len(oldX)
    
        for curr in range(num_points):
            prev = (curr + num_points - 1) % num_points
            next = (curr + 1) % num_points
    
            vnX =  oldX[next] - oldX[curr]
            vnY =  oldY[next] - oldY[curr]
            vnnX, vnnY = normalizeVec(vnX,vnY)
            nnnX = vnnY
            nnnY = -vnnX
    
            vpX =  oldX[curr] - oldX[prev]
            vpY =  oldY[curr] - oldY[prev]
            vpnX, vpnY = normalizeVec(vpX,vpY)
            npnX = vpnY * outer_ccw
            npnY = -vpnX * outer_ccw
    
            bisX = (nnnX + npnX) * outer_ccw
            bisY = (nnnY + npnY) * outer_ccw
    
            bisnX, bisnY = normalizeVec(bisX,  bisY)
            bislen = offset /  np.sqrt(1 + nnnX*npnX + nnnY*npnY)
    
            newX.append(oldX[curr] + bislen * bisnX)
            newY.append(oldY[curr] + bislen * bisnY)
    
    x = [0, 100, 60, 40]
    y = [0, 0, 50, 50]
    makeOffsetPoly(x, y, 20)
    print(newX, newY)
    
    >>>[-29.424478775259594, 129.4244787752596, 66.79706177729007, 33.202938222709925] 
       [-14.14213562373095, -14.14213562373095, 64.14213562373095, 64.14213562373095]
    

    【讨论】:

    • 如果我们的任何边缘有非直线,我们还能做出这样的外形
    • 为曲线定义偏移线通常是非常困难的问题(圆弧除外)。您可以通过小线段来近似曲线。
    • 你可以在空闲时间展示弯曲边缘的任何例子..我尝试使用 cv2.approxPolyDP 进行近似
    • approxPolyDP 假设您已经有顶点数组(顶点太多)。简化后只需应用描述的方法。
    【解决方案2】:

    只需将第一个坐标附加到列表的末尾即可。

    x.append(x[0])
    y.append(y[0])
    newX.append(newX[0])
    newY.append(newY[0])
    

    在绘图之前放置它。这是我的output

    【讨论】:

    • 我已经手动尝试过了,但是偏移线没有给出正确的结果。
    • @Froge 可以用示例说明/或根据您的想法更改代码
    • @k_p 查看编辑。我不确定你所说的偏移线是什么意思
    猜你喜欢
    • 2016-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-19
    • 2013-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多