Welcome to Typophile

# Calculating Bezier curve speed (= tangents), but something smells fishy

## Primary tabs

1 post / 0 new
Offline
Joined: 11 Dec 2007 - 3:19am
Calculating Bezier curve speed (= tangents), but something smells fishy

Dear Bezier masters,

I'm reposting this from here, because it's a different topic and problem now.

I've tried to approach my problem (calculating curve speed) in a more general way, using the general cubic Bezier equation.
I've constructed the first derivative, as suggested. Please correct me, if I made mistakes there. School was a looong time ago. But findings on the internet suggest that I did it right.
The function solveCubic returns as the first argument p1234 (identical to the middle on-curve point calculated by the known splitCubicAtT function, I just skipped the other points for now), then the result of the first derivative.
All are vectors (or coordinates).

The segment used for the results posted below (with t in 0.1 steps) is a quarter of a circle, or a quarter of as close a circle as one can construct with Beziers. The first derivative should then have all equal (more or less) values, right, in case of a circle? In other words, curve speed should be steady at all positions in a circle. Shown in the results in the rightmost column is the absolute value of the vector returned by the first derivative.
But the results differ by 8%. This doesn't look right. I've double-checked for a correct circle pie piece.

Where is the mistake or the misunderstanding?

import numpy, math

def solveCubic(p0, p1, p2, p3, t):
p0, p1, p2, p3 = numpy.array((p0, p1, p2, p3))

a = -p0 + 3.0 * p1 - 3.0 * p2 + p3
b = 3.0 * p0 - 6.0 * p1 + 3.0 * p2
c = -3.0 * p0 + 3.0 * p1
d = p0

# Cubic Bezier
f = a*t**3 + b*t**2 + c*t + d

# First derivative
f1 = 3*a*t**2 + 2*b*t + c

return f, f1

g = CurrentGlyph()
p1 = (g[0][0].points[0].x, g[0][0].points[0].y)
p2 = (g[0][1].points[0].x, g[0][1].points[0].y)
p3 = (g[0][1].points[1].x, g[0][1].points[1].y)
p4 = (g[0][1].points[2].x, g[0][1].points[2].y)

for t in range(11):

f, f1 = solveCubic(p1, p2, p3, p4, t / 10.0)

print "t=%s" % (t/10.0), " - f1=%s=abs %s" % (str(f1).ljust(17), int(math.sqrt( f1[0]**2 + f1[1]**2 )))

The results are:

t=0.0 - f1=[-327. 0.] =abs 327
t=0.1 - f1=[-312.93 -51.33] =abs 317
t=0.2 - f1=[-294.72 -98.52] =abs 310
t=0.3 - f1=[-272.37 -141.57] =abs 306
t=0.4 - f1=[-245.88 -180.48] =abs 305
t=0.5 - f1=[-215.25 -215.25] =abs 304
t=0.6 - f1=[-180.48 -245.88] =abs 305
t=0.7 - f1=[-141.57 -272.37] =abs 306
t=0.8 - f1=[ -98.52 -294.72] =abs 310
t=0.9 - f1=[ -51.33 -312.93] =abs 317
t=1.0 - f1=[ 0. -327.] =abs 327