Application Center - Maplesoft
Our website is currently undergoing maintenance, which may result in occasional errors while browsing. We apologize for any inconvenience this may cause and are working swiftly to restore full functionality. Thank you for your patience.

App Preview:

Frenet frame of a 3D curve

You can switch back to the summary page by clicking here.

Learn about Maple
Download Application


 

crv.mws

Frenet Analysis of Curves

Using Maple and the vec_calc Package

In this worksheet we will see how Maple and the vec_calc package can be used to analyse a parametrized curve. As an example, we will consider:

* The Winding Line on a Torus

which may be parametrized by

r(t) = [(p+q*cos(n*t))*cos(m*t), (p+q*cos(n*t))*sin...

Here p is the big radius, q is the small radius and m and n are the angular rates.

The quantities we will compute are:

* the velocity v = dr/dt

* the acceleration a = d^2*r/(dt^2)

* the jerk j = d^3*r/(dt^3)

* the speed ds/dt = abs(v)

* the arclength s = int(abs(v),t = 0 .. 2*Pi)

* the unit tangent vector T = v/abs(v)

* the unit binormal vector B = v*x*a/abs(v*x*a)

* the unit principal normal vector N = B*x*T

* the curvature kappa = abs(dT/ds) = a.N/(abs(v)^2) = abs(v*x*a)/(abs(v)^3)

* the torsion tau = -(dB/ds.N) = v*x*a.j/(abs(v*x*a)^2)

* the tangential acceleration a[T] = a.T = d^2*s/(dt^2)

* the normal acceleration a[N] = a.N = kappa*v^2

In addition we will animate the drawing of the curve .

We start by initializing the vec_calc package:

> restart;

> libname:=libname,"C:/mylib/vec_calc7":

> with(vec_calc): vc_aliases:

> with(linalg):with(student):with(plots):

Warning, the protected names norm and trace have been redefined and unprotected

Warning, the name changecoords has been redefined

>

Define and Plot the Curve

We enter the function using the makefunction command

> r:=MF(t, [(p+q*cos(n*t))*cos(m*t), (p+q*cos(n*t))*sin(m*t), q*sin(n*t)]);

r := [proc (t) options operator, arrow; (p+q*cos(n*...

We choose values for the parameters: As t goes from 0 to 2*Pi , m tells how many times the curve wraps around the circle of radius p and n tells how many times the curve wraps around the circle of radius q . If the ratio n/m is rational, the curve closes. If n/m is irrational, the curve does not close and has infinite length.

> p:=1; q:=1/2; m:=1; n:=8;

p := 1

q := 1/2

m := 1

n := 8

We plot the curve: (Notice that the op command is needed to strip off the square brackets from the result of r(t) .)

> spacecurve([op(r(t)),t=0..2*Pi], numpoints=193, scaling=constrained, orientation=[0,45], color=blue);

[Maple Plot]

Try the following:

* Click in the plot and drag the mouse. This will give you a better idea about the 3-dimensional shape of the curve.

* Change the numbers m and n . In particular, try m = 8 , n = 1 , or try m = 1 , n = 2*Pi , or try m = 2*Pi , n = 1 . For the last two, the curve does not close.

We can also animate the curve being drawn:

> frames:=24;

frames := 24

> display([seq(spacecurve([op(r(t)), t=0..i*2*Pi/frames], numpoints=8*i, color=blue), i=1..frames)], orientation=[0,45], scaling=constrained, insequence=true);

[Maple Plot]

Click in the plot. Then click on the loop and play buttons. Also try dragging the mouse while the plot is running.

We will add to these plots later.

Before going on, we remove the values of the parameters so the remaining quantites are computed in general whenever possible.

> p:='p'; q:='q'; m:='m'; n:='n';

p := 'p'

q := 'q'

m := 'm'

n := 'n'

We will reassign these parameters whenever necessary.

>

Velocity, Acceleration and Jerk

The velocity is the derivative of the position: (Notice how we can handle the curve as either a vector of expressions or as a vector of functions.)

> diff(r(t),t);

[-q*sin(n*t)*n*cos(m*t)-(p+q*cos(n*t))*sin(m*t)*m, ...

> v:=D(r);

v := [proc (t) options operator, arrow; -q*sin(n*t)...

> v(t);

[-q*sin(n*t)*n*cos(m*t)-(p+q*cos(n*t))*sin(m*t)*m, ...

The acceleration is the derivative of the velocity:

> a:=D(v);

a := [proc (t) options operator, arrow; -q*cos(n*t)...
a := [proc (t) options operator, arrow; -q*cos(n*t)...

> a(t);

[-q*cos(n*t)*n^2*cos(m*t)+2*q*sin(n*t)*n*sin(m*t)*m...
[-q*cos(n*t)*n^2*cos(m*t)+2*q*sin(n*t)*n*sin(m*t)*m...

The jerk is the derivative of the acceleration:

> j:=D(a);

j := [proc (t) options operator, arrow; q*sin(n*t)*...
j := [proc (t) options operator, arrow; q*sin(n*t)*...

> j(t);

[q*sin(n*t)*n^3*cos(m*t)+3*q*cos(n*t)*n^2*sin(m*t)*...
[q*sin(n*t)*n^3*cos(m*t)+3*q*cos(n*t)*n^2*sin(m*t)*...

There are also vec_calc commands to directly compute the velocity, acceleration and jerk:

> v2:=Cv(r);

v2 := [proc (t) options operator, arrow; -q*sin(n*t...

> a2:=Ca(r);

a2 := [proc (t) options operator, arrow; -q*cos(n*t...
a2 := [proc (t) options operator, arrow; -q*cos(n*t...

> j2:=Cj(r);

j2 := [proc (t) options operator, arrow; q*sin(n*t)...
j2 := [proc (t) options operator, arrow; q*sin(n*t)...

We check the answers are the same:

> v(t)-v2(t);

[0, 0, 0]

> a(t)-a2(t);

[0, 0, 0]

> j(t)-j2(t);

[0, 0, 0]

>

Speed and Arclength

The speed is the length of the velocity:

> speed:=simplify(len(v(t)));

speed := sqrt(p^2*m^2+2*m^2*p*q*cos(n*t)+m^2*q^2*co...

The arclength is the integral of the speed: ( Maple is unable to compute the exact value using the value command.)

> Int(speed,t=0..2*Pi); #arclength:=value(%);

Int(sqrt(p^2*m^2+2*m^2*p*q*cos(n*t)+m^2*q^2*cos(n*t...

So we give values to the parameters and use evalf to get a decimal approximation:

> p:=1; q:=1/2; m:=1; n:=8;

p := 1

q := 1/2

m := 1

n := 8

> Int(speed,t=0..2*Pi); arclength:=evalf(%);

Int(sqrt(17+cos(8*t)+1/4*cos(8*t)^2),t = 0 .. 2*Pi)...

arclength := 25.99570355

Notice that since m = 1 , n = 8 , the arclength is a little more than 8 times the circumference of a circle of radius q = 1/2 :

> 8*2*Pi*q; evalf(%);

8*Pi

25.13274123

There is also a vec_calc command to directly compute the arclength integral as a function of its two endpoints:

> L:=CL(r);

L := proc (a, b) options operator, arrow; Int(1/2*s...
L := proc (a, b) options operator, arrow; Int(1/2*s...
L := proc (a, b) options operator, arrow; Int(1/2*s...

> L(0,2*Pi); evalf(%);

Int(1/2*sqrt(73-11776*cos(t)^6+1984*cos(t)^4+42752*...
Int(1/2*sqrt(73-11776*cos(t)^6+1984*cos(t)^4+42752*...
Int(1/2*sqrt(73-11776*cos(t)^6+1984*cos(t)^4+42752*...

25.99570355

Once again, we unassign the parameters:

> p:='p'; q:='q'; m:='m'; n:='n';

p := 'p'

q := 'q'

m := 'm'

n := 'n'

>

Frenet Frame

The vectors T , N and B form a right handed triplet of unit vectors called the Frenet frame for the curve.

The unit tangent vector is the unit vector in the direction of the velocity:

> T:=v(t)/speed;

T := [-q*sin(n*t)*n*cos(m*t)-(p+q*cos(n*t))*sin(m*t...

The unit binormal is the unit vector perpendicular to the instantaneous plane of the motion in the direction of v x a . We first need

> vxa:=simplify(v(t) &x a(t));

vxa := [q*n*(q*n^2*sin(m*t)-sin(n*t)*n*cos(m*t)*m*p...
vxa := [q*n*(q*n^2*sin(m*t)-sin(n*t)*n*cos(m*t)*m*p...
vxa := [q*n*(q*n^2*sin(m*t)-sin(n*t)*n*cos(m*t)*m*p...

> lvxa:=simplify(len(vxa));

lvxa := sqrt(q^2*n^4*m^2*p^2+m^6*q^4*cos(n*t)^4+4*m...
lvxa := sqrt(q^2*n^4*m^2*p^2+m^6*q^4*cos(n*t)^4+4*m...
lvxa := sqrt(q^2*n^4*m^2*p^2+m^6*q^4*cos(n*t)^4+4*m...

Then the unit binormal is

> B:=vxa/lvxa;

B := [q*n*(q*n^2*sin(m*t)-sin(n*t)*n*cos(m*t)*m*p+q...
B := [q*n*(q*n^2*sin(m*t)-sin(n*t)*n*cos(m*t)*m*p+q...
B := [q*n*(q*n^2*sin(m*t)-sin(n*t)*n*cos(m*t)*m*p+q...
B := [q*n*(q*n^2*sin(m*t)-sin(n*t)*n*cos(m*t)*m*p+q...
B := [q*n*(q*n^2*sin(m*t)-sin(n*t)*n*cos(m*t)*m*p+q...
B := [q*n*(q*n^2*sin(m*t)-sin(n*t)*n*cos(m*t)*m*p+q...

Since T , N and B form a right handed triplet, in that order, we have that the unit principal normal is: (The evall command multiplies the scalars into the vectors.)

> N:=simplify(evall(B) &x evall(T));

N := [(-q^2*n^2*cos(n*t)^2*cos(m*t)*m^2*p-q^3*n^4*c...
N := [(-q^2*n^2*cos(n*t)^2*cos(m*t)*m^2*p-q^3*n^4*c...
N := [(-q^2*n^2*cos(n*t)^2*cos(m*t)*m^2*p-q^3*n^4*c...
N := [(-q^2*n^2*cos(n*t)^2*cos(m*t)*m^2*p-q^3*n^4*c...
N := [(-q^2*n^2*cos(n*t)^2*cos(m*t)*m^2*p-q^3*n^4*c...
N := [(-q^2*n^2*cos(n*t)^2*cos(m*t)*m^2*p-q^3*n^4*c...
N := [(-q^2*n^2*cos(n*t)^2*cos(m*t)*m^2*p-q^3*n^4*c...
N := [(-q^2*n^2*cos(n*t)^2*cos(m*t)*m^2*p-q^3*n^4*c...
N := [(-q^2*n^2*cos(n*t)^2*cos(m*t)*m^2*p-q^3*n^4*c...
N := [(-q^2*n^2*cos(n*t)^2*cos(m*t)*m^2*p-q^3*n^4*c...
N := [(-q^2*n^2*cos(n*t)^2*cos(m*t)*m^2*p-q^3*n^4*c...
N := [(-q^2*n^2*cos(n*t)^2*cos(m*t)*m^2*p-q^3*n^4*c...
N := [(-q^2*n^2*cos(n*t)^2*cos(m*t)*m^2*p-q^3*n^4*c...
N := [(-q^2*n^2*cos(n*t)^2*cos(m*t)*m^2*p-q^3*n^4*c...
N := [(-q^2*n^2*cos(n*t)^2*cos(m*t)*m^2*p-q^3*n^4*c...
N := [(-q^2*n^2*cos(n*t)^2*cos(m*t)*m^2*p-q^3*n^4*c...

There are also vec_calc commands to directly compute T , N and B as vector functions:

> T2:=CT(r);

T2 := [proc (t) options operator, arrow; -(q*sin(n*...
T2 := [proc (t) options operator, arrow; -(q*sin(n*...

> B2:=CB(r);

B2 := [proc (t) options operator, arrow; q*n*(q*n^2...
B2 := [proc (t) options operator, arrow; q*n*(q*n^2...
B2 := [proc (t) options operator, arrow; q*n*(q*n^2...
B2 := [proc (t) options operator, arrow; q*n*(q*n^2...
B2 := [proc (t) options operator, arrow; q*n*(q*n^2...
B2 := [proc (t) options operator, arrow; q*n*(q*n^2...
B2 := [proc (t) options operator, arrow; q*n*(q*n^2...
B2 := [proc (t) options operator, arrow; q*n*(q*n^2...
B2 := [proc (t) options operator, arrow; q*n*(q*n^2...
B2 := [proc (t) options operator, arrow; q*n*(q*n^2...
B2 := [proc (t) options operator, arrow; q*n*(q*n^2...

> N2:=CN(r);

N2 := [proc (t) options operator, arrow; -(q^3*n^4*...
N2 := [proc (t) options operator, arrow; -(q^3*n^4*...
N2 := [proc (t) options operator, arrow; -(q^3*n^4*...
N2 := [proc (t) options operator, arrow; -(q^3*n^4*...
N2 := [proc (t) options operator, arrow; -(q^3*n^4*...
N2 := [proc (t) options operator, arrow; -(q^3*n^4*...
N2 := [proc (t) options operator, arrow; -(q^3*n^4*...
N2 := [proc (t) options operator, arrow; -(q^3*n^4*...
N2 := [proc (t) options operator, arrow; -(q^3*n^4*...
N2 := [proc (t) options operator, arrow; -(q^3*n^4*...
N2 := [proc (t) options operator, arrow; -(q^3*n^4*...
N2 := [proc (t) options operator, arrow; -(q^3*n^4*...
N2 := [proc (t) options operator, arrow; -(q^3*n^4*...
N2 := [proc (t) options operator, arrow; -(q^3*n^4*...
N2 := [proc (t) options operator, arrow; -(q^3*n^4*...
N2 := [proc (t) options operator, arrow; -(q^3*n^4*...
N2 := [proc (t) options operator, arrow; -(q^3*n^4*...

We again check the answers are the same:

> simplify(evall(T-T2(t)));

[0, 0, 0]

> evall(B-B2(t));

[0, 0, 0]

Maple is unable to show the difference of the N vectors is zero. So it needs some help. We show the square of each component is the same by showing the ratio is one:

> N[1]^2/N2(t)[1]^2;

(-q^2*n^2*cos(n*t)^2*cos(m*t)*m^2*p-q^3*n^4*cos(n*t...
(-q^2*n^2*cos(n*t)^2*cos(m*t)*m^2*p-q^3*n^4*cos(n*t...
(-q^2*n^2*cos(n*t)^2*cos(m*t)*m^2*p-q^3*n^4*cos(n*t...
(-q^2*n^2*cos(n*t)^2*cos(m*t)*m^2*p-q^3*n^4*cos(n*t...
(-q^2*n^2*cos(n*t)^2*cos(m*t)*m^2*p-q^3*n^4*cos(n*t...
(-q^2*n^2*cos(n*t)^2*cos(m*t)*m^2*p-q^3*n^4*cos(n*t...

> N[2]^2/N2(t)[2]^2;

1

> N[3]^2/N2(t)[3]^2;

1

>

Plot the Frame

We want to add the Frenet frame to our plot and animation of the curve.

We first redefine the parameters.

> p:=1; q:=1/2; m:=1; n:=8;

p := 1

q := 1/2

m := 1

n := 8

Next we replot the curve but stop at a random endpoint:

> tfinal:=1.2*Pi;

tfinal := 1.2*Pi

> crvplot:=spacecurve([op(r(t)),t=0..tfinal], numpoints=193, scaling=constrained, orientation=[0,45], color=blue): crvplot;

[Maple Plot]

Now we plot the tangent vector T using a dot-to-dot plot, but locate the vector at the tip of the curve: (Note: We need to use evall to add the two vectors.)

> Tplot:=spacecurve([r(tfinal),evall(r(tfinal)+T2(tfinal))], color=red): Tplot;

[Maple Plot]

In addition, we plot the normal N and the binormal B and display all three with the original curve:

> Nplot:=spacecurve([r(tfinal),evall(r(tfinal)+N2(tfinal))], color=cyan):

> Bplot:=spacecurve([r(tfinal),evall(r(tfinal)+B2(tfinal))], color=magenta):

> display({crvplot,Tplot,Nplot,Bplot});

[Maple Plot]

We are finally ready to animate the curve:

> frames:=50;

frames := 50

> plotlist:=NULL:

> for i from 1 to frames do
tfinal:=i*2*Pi/frames;
crvplot:=spacecurve([op(r(t)),t=0..tfinal], numpoints=193, scaling=constrained, orientation=[0,45], color=blue):
Tplot:=spacecurve([r(tfinal),evall(r(tfinal)+T2(tfinal))], color=red):
Nplot:=spacecurve([r(tfinal),evall(r(tfinal)+N2(tfinal))], color=cyan):
Bplot:=spacecurve([r(tfinal),evall(r(tfinal)+B2(tfinal))], color=magenta):
plotlist:=plotlist,display({crvplot,Tplot,Nplot,Bplot});
od:

> display([plotlist], orientation=[0,45], scaling=constrained, insequence=true);

[Maple Plot]

Before going on, we again remove the values of the parameters.

> p:='p'; q:='q'; m:='m'; n:='n';

p := 'p'

q := 'q'

m := 'm'

n := 'n'

>

Curvature and Torsion

The curvature measures the rate at which the curve is turning. There are a couple ways to compute the curvature. We do two and compare them:

> kappa:=(a(t) &. N)/speed^2;

kappa := (q^2*n^4*m^2*p^2+m^6*q^4*cos(n*t)^4+4*m^2*...
kappa := (q^2*n^4*m^2*p^2+m^6*q^4*cos(n*t)^4+4*m^2*...
kappa := (q^2*n^4*m^2*p^2+m^6*q^4*cos(n*t)^4+4*m^2*...

> Kappa:=simplify(lvxa/speed^3);

Kappa := (q^2*n^4*m^2*p^2+m^6*q^4*cos(n*t)^4+4*m^2*...
Kappa := (q^2*n^4*m^2*p^2+m^6*q^4*cos(n*t)^4+4*m^2*...
Kappa := (q^2*n^4*m^2*p^2+m^6*q^4*cos(n*t)^4+4*m^2*...

> kappa-Kappa;

0

The torsion measures the rate at which the plane of the curve is turning.

> tau:=(vxa &. j(t))/lvxa^2;

tau := -q*n*m*(2*q*p*n^2*m^2+m^2*q^2*cos(n*t)^3*n^2...
tau := -q*n*m*(2*q*p*n^2*m^2+m^2*q^2*cos(n*t)^3*n^2...
tau := -q*n*m*(2*q*p*n^2*m^2+m^2*q^2*cos(n*t)^3*n^2...
tau := -q*n*m*(2*q*p*n^2*m^2+m^2*q^2*cos(n*t)^3*n^2...

There are also vec_calc commands to directly compute the curvature and torsion as functions

> kappa2:=Ck(r);

kappa2 := proc (t) options operator, arrow; (q^2*n^...
kappa2 := proc (t) options operator, arrow; (q^2*n^...
kappa2 := proc (t) options operator, arrow; (q^2*n^...
kappa2 := proc (t) options operator, arrow; (q^2*n^...
kappa2 := proc (t) options operator, arrow; (q^2*n^...
kappa2 := proc (t) options operator, arrow; (q^2*n^...
kappa2 := proc (t) options operator, arrow; (q^2*n^...

> tau2:=Ct(r);

tau2 := proc (t) options operator, arrow; q*n*m*(co...
tau2 := proc (t) options operator, arrow; q*n*m*(co...
tau2 := proc (t) options operator, arrow; q*n*m*(co...
tau2 := proc (t) options operator, arrow; q*n*m*(co...

We again check these agree: Again Maple had trouble simplifying the difference of the curvatures, so we compute the ratio of the squares:

> simplify(kappa^2/kappa2(t)^2);

1

> simplify(tau-tau2(t));

0

>

Tangential and Normal Acceleration

The acceleration can be decomposed into components parallel and perpendicular to the direction of motion: a = a[T]*T+a[N]*N The coefficients are the tangential and normal accelerations. We compute each of them in two ways and compare.

> aT:=a(t) &. evall(T);

aT := -q*n*sin(n*t)*m^2*(p+q*cos(n*t))/(p^2*m^2+2*m...

> AT:=simplify(diff(speed,t));

AT := -q*n*sin(n*t)*m^2*(p+q*cos(n*t))/(p^2*m^2+2*m...

> aT-AT;

0

> aN:=a(t) &. evall(N);

aN := (q^2*n^4*m^2*p^2+m^6*q^4*cos(n*t)^4+4*m^2*q^4...
aN := (q^2*n^4*m^2*p^2+m^6*q^4*cos(n*t)^4+4*m^2*q^4...
aN := (q^2*n^4*m^2*p^2+m^6*q^4*cos(n*t)^4+4*m^2*q^4...

> AN:=kappa*speed^2;

AN := (q^2*n^4*m^2*p^2+m^6*q^4*cos(n*t)^4+4*m^2*q^4...
AN := (q^2*n^4*m^2*p^2+m^6*q^4*cos(n*t)^4+4*m^2*q^4...
AN := (q^2*n^4*m^2*p^2+m^6*q^4*cos(n*t)^4+4*m^2*q^4...

> aN-AN;

0

Again there vec_calc commands to directly compute the tangential and normal accelerations.

> aT2:=CaT(r);

aT2 := proc (t) options operator, arrow; -q*n*sin(n...

> aN2:=CaN(r);

aN2 := proc (t) options operator, arrow; (q^2*n^4*m...
aN2 := proc (t) options operator, arrow; (q^2*n^4*m...
aN2 := proc (t) options operator, arrow; (q^2*n^4*m...
aN2 := proc (t) options operator, arrow; (q^2*n^4*m...
aN2 := proc (t) options operator, arrow; (q^2*n^4*m...
aN2 := proc (t) options operator, arrow; (q^2*n^4*m...

Again we check:

> aT-aT2(t);

0

> aN^2-aN2(t)^2;simplify(%);

0

0

>