Thomas Wagenaar
Thomas Wagenaar

Reputation: 6779

Force zero normal acceleration at start/end of Bezier curve

Below I have attached a Python script that calculates a 5-point Bezier curve and calculates the normal acceleration of that curve. The result looks as follows:

enter image description here

We see on the right-hand side that the normal acceleration at the start and end of curve is nonzero. Is there anyway to make sure that the normal acceleration is zero at the boundaries and also remains smooth? I have tried setting high weights for the 2nd and 4th point, this works but does not force it to absolute zero.

Note! it's basically similar to, how do we force the curvature to be zero at the boundaries?

import numpy as np
from scipy.special import comb
import matplotlib.pyplot as plt

# Order of bezier curve
N = 5

# Generate points
np.random.seed(2)
points = np.random.rand(N,2)

''' Calculate bezier curve '''
t = np.linspace(0,1,1000)

polys = np.asarray([comb(N-1, i) * ( (1-t)**(N-1-i) ) * t**i for i in range(0,N)])

curve = np.zeros((t.shape[0], 2))
curve[:,0] = points[:,0] @ polys
curve[:,1] = points[:,1] @ polys

''' Calculate normal acceleration '''
velocity     = np.gradient(curve, axis=0) * t.shape[0]
acceleration = np.gradient(velocity, axis=0) * t.shape[0]

a_tangent    = acceleration * velocity / (velocity[:,[0]]**2 + velocity[:,[1]]**2)
a_tangent    = a_tangent * velocity

a_normal = acceleration - a_tangent
a_normal_mag = np.linalg.norm(a_normal,axis=1)

''' Plotting'''
fig,axes = plt.subplots(1,2)
axes[0].scatter(points[:,0], points[:,1])
axes[0].plot(curve[:,0], curve[:,1])
axes[0].set_xlabel('x(t)')
axes[0].set_xlabel('y(t)')
axes[1].plot(t,a_normal_mag)
axes[1].set_xlabel('t')
axes[1].set_ylabel('a_n(t)')

plt.show()

Upvotes: 2

Views: 272

Answers (1)

fang
fang

Reputation: 3633

If you want the Bezier curve to have zero 2nd derivative or zero curvature at the ends, the control points can no longer be arbitrary and need to follow a certain "pattern".

For a Bezier curve, its first and 2nd derivatives at t=0 are

C'(0)=d(P1-P0)
C"(0)=d(d-1)(P2-2P1+P0)

where d = degree and P0,P1 and P2 are the first 3 control points.

If you want the curvature at t=0 to be zero, you can choose one of the following 3 conditions:

a) force first derivative to be zero ==> P0=P1.
b) force 2nd derivative to be zero ==> P2-2P1+P0 = 0,
c) force first and 2nd derivatives to be parallel to each other ==> P0, P1 and P2 are collinear.

If you choose to force parallel first and 2nd derivatives at both t=0 and t=1, for a Bezier curve of 5 control points, this means that P2 will be at the intersection of Line(P0,P1) and Line(P3,P4).

Upvotes: 2

Related Questions