As shown in the image, formulae or method how to calculate smooth curved line is needed.The red line is the line which will look at the end after solving.
I'll appreciate your help / discussion.
I need mathematical formulae and may be how to solve it using scipy python package.
Actually, you will gain more flexibility if you use cubic Bezier curves.
This for the first problem:
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()
The advantage of the cubic Bezier is that you can also seamlessly deal with the cases such as where the two direction lines don't cross. For example
x2, y2, heading2 = 1.0, 1.0, 0.0
with output