计算两点之间满足两点航向的平滑曲线的公式/方法

问题描述 投票:0回答:1


如图所示,需要如何计算平滑曲线的公式或方法。红线是求解后看到最后的线。

我将感谢您的帮助/讨论。

我需要数学公式,可能是如何使用 scipy python 包来解决它。

python math formula smoothing curve
1个回答
0
投票

实际上,如果使用三次贝塞尔曲线,您将获得更大的灵活性。

这是第一个问题:

import math
import numpy as np
import matplotlib.pyplot as plt

#-----------------------------

def length( vector ): return np.linalg.norm( vector )      # length of a vector
def normalise( vector ): return vector / length(vector)    # normalise a vector (numpy array)

#-----------------------------

class Bezier:
    '''class for Cubic Bezier curve'''
    def __init__( self, q0, q1, q2, q3 ):
        self.p0 = np.array( q0 )
        self.p1 = np.array( q1 )
        self.p2 = np.array( q2 )
        self.p3 = np.array( q3 )

    def pt( self, t ):
        return ( 1.0 - t ) ** 3 * self.p0 + 3.0 * t * ( 1.0 - t ) ** 2 * self.p1 + 3.0 * t ** 2 * ( 1.0 - t ) * self.p2 + t ** 3 * self.p3

    def curve( self, n ):
        crv = []
        for t in np.linspace( 0.0, 1.0, n ):
            crv.append( self.pt( t ) )
        return crv

#-----------------------------

def drawBezier( x1, y1, heading1, x2, y2, heading2, n ):
    '''Turns two points plus headings into cubic Bezier control points [ P0, P1, P2, P3 ] by adding intermediate control points'''
    result = []

    rad1, rad2 = heading1 * math.pi / 180, heading2 * math.pi / 180
    d1 = np.array( [ np.sin( rad1 ), np.cos( rad1 ) ] )    # direction vector at point 1
    d2 = np.array( [ np.sin( rad2 ), np.cos( rad2 ) ] )

    p0 = np.array( ( x1, y1 ) )                            # start point of Bezier curve
    p3 = np.array( ( x2, y2 ) )                            # end point of Bezier curve
    p1 = p0 + d1 * length( p3 - p0 ) / 2.0                 # use direction at P0 to get P1
    p2 = p3 - d2 * length( p3 - p0 ) / 2.0                 # use direction at p3 to get P2

    arc = Bezier( p0, p1, p2, p3 )                         # define a cubic Bezier object

    x = [];   y = []
    for pt in arc.curve( n ):
        x.append( pt[0] )
        y.append( pt[1] )
    plt.plot( x, y )
    
#-----------------------------

x1, y1, heading1 = 0.0, 0.0, 0.0
x2, y2, heading2 = 1.0, 1.0, 90.0
drawBezier( x1, y1, heading1, x2, y2, heading2, 100 )
plt.plot( [ x1, x2 ], [ y1, y2 ], 'o' )                   # plot original support points
plt.show()

三次贝塞尔曲线的优点是还可以无缝处理两条方向线不交叉等情况。例如

x2, y2, heading2 = 1.0, 1.0, 0.0

有输出

© www.soinside.com 2019 - 2024. All rights reserved.