Arc Length, TNB-frames, Curvature, and Torsion 

 

To execute all commands select "EditExecuteWorksheet". Be warned: This takes about 2-3 minutes to execute on my office desktop. 

 

Maple worksheet: curvature.mw 

As usual we begin by wiping memory and reloading the relevant packages. We also let Maple know that the variable "t" is a real number for the rest of this worksheet. 

 

> restart;
with(VectorCalculus):
with(plots):
assume(t::real);
 

 

Example: Recall that we can parametrize the ellipse VectorCalculus:-`+`(VectorCalculus:-`*`(`*`(`^`(VectorCalculus:-`+`(x, -3), 2)), `/`(1, `*`(`^`(2, 2)))), VectorCalculus:-`*`(`*`(`^`(VectorCalculus:-`+`(y, 2), 2)), `/`(1, `*`(`^`(5, 2))))) = 1 using sines and cosines as follows:  x(t) = VectorCalculus:-`+`(VectorCalculus:-`*`(2, cos(t)), 3), y(t) = VectorCalculus:-`+`(VectorCalculus:-`*`(5, sin(t)), -2), (and z(t) = 0) where `and`(`<=`(0, t), `<=`(t, VectorCalculus:-`*`(2, Pi))). Let's define a vector valued function called "r" so that the graph of r(t) is this ellipse. 

 

> r := t -> <2*cos(t)+3,5*sin(t)-2,0>:
'r(t)' = r(t);
 

r(t) = Vector[column](%id = 18446744078108598510) (1)
 

 

Next, we define the arc length function s(t) for this parametrization and then evalute the arc length function when t = VectorCalculus:-`*`(2, Pi)to compute the arc length of the ellipse. 

 

Recall that the arc length function is given by s(t) = int(abs(eval(diff(r(x), x), x = u)), u = a .. t)  where `<=`(a, t). 

 

> s := t -> int(Norm(diff(r(u),u)),u=0..t):
's(t)' = s(t);

s(2*Pi) = evalf(s(2*Pi));
 

 

s(t) = `+`(`*`(10, `*`(EllipticE(`+`(`*`(`/`(1, 5), `*`(`^`(21, `/`(1, 2)))))))), `-`(`*`(5, `*`(EllipticE(`*`(`^`(`+`(1, `-`(`*`(`^`(cos(t), 2)))), `/`(1, 2))), `+`(`*`(`/`(1, 5), `*`(`^`(21, `/`(1, ...
`+`(`*`(20, `*`(EllipticE(`+`(`*`(`/`(1, 5), `*`(`^`(21, `/`(1, 2))))))))) = 23.01311260 (2)
 

 

Notice that the arc length of an ellipse involves elliptic functions -- surprise! 

 

Alternatively we could use the VectorCalculus command "ArcLength" (this might be the smarter thing to do rather than reinventing the wheel). 

 

> s := t -> ArcLength(r(u),u=0..t):
's(t)' = s(t);

s(2*Pi) = evalf(s(2*Pi));
 

 

s(t) = `+`(`*`(10, `*`(EllipticE(`+`(`*`(`/`(1, 5), `*`(`^`(21, `/`(1, 2)))))))), `-`(`*`(5, `*`(EllipticE(`*`(`^`(`+`(1, `-`(`*`(`^`(cos(t), 2)))), `/`(1, 2))), `+`(`*`(`/`(1, 5), `*`(`^`(21, `/`(1, ...
`+`(`*`(20, `*`(EllipticE(`+`(`*`(`/`(1, 5), `*`(`^`(21, `/`(1, 2))))))))) = 23.01311260 (3)
 

 

Using the "diff", "Norm", and "&x" (cross product) commands, we can construct the unit tangent, unit normal, and binormal functions for this ellipse. 

 

Recall that T(t) = r'(t) / |r'(t)|,  N(t) = T '(t) / |T '(t)|,  and B(t) = T(t) N(t). 

 

> T := t -> simplify(1/Norm(diff(r(t),t))*diff(r(t),t)):
'T(t)' = T(t);

N := t -> simplify(1/Norm(diff(T(t),t))*diff(T(t),t)):
'N(t)' = N(t);

B := t -> simplify(T(t) &x N(t)):
'B(t)' = B(t);
 

 

 

T(t) = Vector[column](%id = 18446744078115415214)
N(t) = Vector[column](%id = 18446744078115408822)
B(t) = Vector[column](%id = 18446744078115404366) (4)
 

 

VectorCalculus has the built in command "TNBFrame" which does all this for us. 

 

> ellipseFrame := TNBFrame(r(u),u);

T := t -> simplify(subs(u=t,ellipseFrame[1])):
'T(t)' = T(t);

N := t -> simplify(subs(u=t,ellipseFrame[2])):
'N(t)' = N(t);

B := t -> simplify(subs(u=t,ellipseFrame[3])):
'B(t)' = B(t);
 

 

 

 

Vector[column](%id = 18446744078115385822), Vector[column](%id = 18446744078115386062), Vector[column](%id = 18446744078115386302)
T(t) = Vector[column](%id = 18446744078115386542)
N(t) = Vector[column](%id = 18446744078115386782)
B(t) = Vector[column](%id = 18446744078115387142) (5)
 

 

Note: Our computations yielding the TNB-frame involved VectorCalculus package vectors whereas the TNBFrame command yields "arrays" (old style vectors). 

 

Next, let's plot the ellipse together with its TNB-frame at the point t = VectorCalculus:-`*`(Pi, `/`(1, 2)). 

 

> curvePlot := spacecurve(r(t),t=0..2*Pi,color=black,thickness=3):
TPlot := arrow(r(Pi/2),T(Pi/2),shape=arrow,color=blue):
NPlot := arrow(r(Pi/2),N(Pi/2),shape=arrow,color=green):
BPlot := arrow(r(Pi/2),B(Pi/2),shape=arrow,color=red):
display({curvePlot,TPlot,NPlot,BPlot},scaling=constrained,orientation=[126,62],viewpoint=circleleft);
 

Plot_2d
 

 

Now we define the curvature function and plot curvature. Remember that kappa(t) = VectorCalculus:-`*`(abs(eval(diff(T(x), x), x = t)), `/`(1, `*`(abs(eval(diff(r(x), x), x = t))))) 

 

> kappa := t -> simplify(subs(u=t,Norm(diff(T(u),u))/Norm(diff(r(u),u)))):
'kappa(t)' = kappa(t);
 

kappa(t) = `+`(`/`(`*`(10, `*`(csgn(`/`(1, `*`(`+`(`*`(21, `*`(`^`(cos(t), 2))), 4)))))), `*`(`^`(`+`(`*`(21, `*`(`^`(cos(t), 2))), 4), `/`(3, 2))))) (6)
 

 

...Or using the built-in function... 

 

> simplify(Curvature(r(t),t));

plot(kappa(t),t=0..2*Pi);
 

 

`+`(`/`(`*`(10), `*`(`^`(`+`(`*`(21, `*`(`^`(cos(t), 2))), 4), `/`(3, 2)))))
Plot_2d
 

 

The osculating circle at t has radius `/`(1, `*`(kappa(t))) (one over curvature). It's center is located at VectorCalculus:-`+`(r(t), VectorCalculus:-`*`(`/`(1, `*`(kappa(t))), N(t))) [1/kappa(t) units away from the curve in the unit normal direction] and it's parallel to both T(t) and N(t).  

 

The osculating plane is the plane through the point r(t) with normal vector is given by B(t) or alternatively it's parallel to both T(t) and N(t).  

 

Let's plot the curve, the osculating circle at t = VectorCalculus:-`*`(Pi, `/`(1, 2)), and the osculating plane at t = VectorCalculus:-`*`(Pi, `/`(1, 2)) together. 

 

> #
# rCirc(t,u) sweeps out the osculating circle at t as u varies from 0 to 2*Pi.
#
rCirc := (t,u) -> simplify(r(t)+1/kappa(t)*N(t)+1/kappa(t)*T(t)*cos(u)+1/kappa(t)*N(t)*sin(u)):
'rCirc(t,u)'=rCirc(t,u);

oscCircPlot := spacecurve(rCirc(Pi/2,u),u=0..2*Pi,color=blue,thickness=2):
oscPlanePlot := plot3d(r(Pi/2)+T(Pi/2)*t1+N(Pi/2)*t2,t1=-10..10,t2=-5..20,color=yellow):
display({curvePlot,oscCircPlot,oscPlanePlot},scaling=constrained,orientation=[61,52],viewpoint=circleleft);
 

 

rCirc(t, u) = Vector[column](%id = 18446744078115366782)
rCirc(t, u) = Vector[column](%id = 18446744078115366782)
rCirc(t, u) = Vector[column](%id = 18446744078115366782)
rCirc(t, u) = Vector[column](%id = 18446744078115366782)
rCirc(t, u) = Vector[column](%id = 18446744078115366782)
rCirc(t, u) = Vector[column](%id = 18446744078115366782)
rCirc(t, u) = Vector[column](%id = 18446744078115366782)
Plot_2d
 

 

Torsion is a measure of how a curve "bends" out of its osculating planes. This curve's torsion is zero because the curve is planar (it doesn't "bend" out of it's osculating plane at all). We can compute torsion using the built in function. 

 

> tau := t -> simplify(subs(u=t,Torsion(r(u),u))):
'tau(t)' = tau(t);
 

tau(t) = 0 (7)
 

 

Example:  Consider the following curve parametrized by 

 

> r := t -> <t,t^2,5*sin(t)>:
'r(t)' = r(t);
 

r(t) = Vector[column](%id = 18446744078156158606) (8)
 

 

and `and`(`<=`(VectorCalculus:-`-`(VectorCalculus:-`*`(2, Pi)), t), `<=`(t, VectorCalculus:-`*`(2, Pi))).   

 

First, we'll plot this curve. 

 

> spacecurve(r(t),t=-2*Pi..2*Pi,numpoints=5000,scaling=constrained,color=blue,thickness=3,axes=boxed,viewpoint=circleleft);
 

Plot_2d
 

 

Next, let's compute its arc length and plot its curvature. 

 

Since Maple cannot find an exact arc length, we'll use "evalf" to get a decimal approximation. 

 

> "Arc Length" = evalf(ArcLength(r(t),t=-2*Pi..2*Pi));

plot(Curvature(r(t)),t=-2*Pi..2*Pi);
 

 

Arc Length
Plot_2d
 

 

Example: Consider the twisted cubic: 

 

> r := t -> <t,t^2,t^3>:
'r(t)' = r(t);
spacecurve(r(t),t=-1..2,color=blue,thickness=3,axes=boxed,scaling=constrained,orientation=[10,80-5],viewpoint=circleleft);
 

 

r(t) = Vector[column](%id = 18446744078156146438)
Plot_2d
 

 

Let's find the TNB-frame of r(t) and then plot the curvature and torsion for this curve.
 

> tnbFrame := TNBFrame(r(t),t):

T := tnbFrame[1]:
N := tnbFrame[2]:
B := tnbFrame[3]:
"[T,N,B]" = [T,N,B];

plot(Curvature(r(t),t),t=-1..2,title="Curvature");

plot(Torsion(r(t),t),t=-1..2,title="Torsion");
 

 

 

[T,N,B]
Plot_2d
Plot_2d
 

 

Now let's plot the osculating circle and tangent line for the twisted cubic at the point t = 1 along with a plot of the twisted cubic itself. 

 

> # Plug t=1 into the unit Tangent and unit Normal functions.
# The radius of the osculating circle is 1/kappa (the curvature).
T1 := subs(t=1,T);
N1 := subs(t=1,N);
R := 1/subs(t=1,Curvature(r(t),t));

cubicPlot := spacecurve(r(t),t=-1..2,color=blue,thickness=3,axes=boxed,scaling=constrained,orientation=[90,75]):
oscCircle := spacecurve(r(1)+R*N1+R*cos(t)*T1+R*sin(t)*N1,t=0..2*Pi,color=green,thickness=2):
tangent := spacecurve(r(1)+t*T1,t=-4..6,color=red,thickness=2):
display(oscCircle,cubicPlot,tangent,viewpoint=circleleft);
 

 

 

 

Vector[column](%id = 18446744078156113910)
Vector[column](%id = 18446744078156114030)
`+`(`*`(`/`(1, 38), `*`(`^`(76, `/`(1, 2)), `*`(`^`(49, `/`(1, 2)), `*`(`^`(14, `/`(1, 2)))))))
Plot_2d
 

 

Example:  Let's begin by plotting a helix. 

 

> spacecurve(<2*cos(t),2*sin(t),t>,t=-2*Pi..2*Pi,axes=boxed,scaling=constrained,viewpoint=circleleft);
 

Plot_2d
 

 

Now let's try that again using a more "general approach". Instead of punching the parameterization into "spacecure" let's first define it separately so we have it saved for later. 

 

Note: Maple uses the notation "e[x]" for the unit vector "i", "e[y]" for the unit vector "j", and "e[z]" for the unit vector "k". 

 

> r := t -> <2*cos(t),2*sin(t),t>:
'r(t)' = r(t);

spacecurve(r(t),t=-2*Pi..2*Pi,axes=boxed,scaling=constrained,viewpoint=circleleft);
 

 

r(t) = Vector[column](%id = 18446744078115410398)
Plot_2d
 

 

It's easy to differentiate and integrate vector valued functions.  

 

> 'r(t)' = r(t);
Diff(r(t),t) = diff(r(t),t);
Int(r(t),t) = int(r(t),t);
 

 

 

r(t) = Vector[column](%id = 18446744078115411118)
Diff(Vector[column](%id = 18446744078115411238), t) = Vector[column](%id = 18446744078115411478)
Int(Vector[column](%id = 18446744078115411718), t) = Vector[column](%id = 18446744078115412078) (9)
 

 

Let's plot the helix together with it's tangent line at t = Pi. 

 

The derivative gives the direction of the line, and the parameterization will give a point on the line. The "subs" command allows us to substitute u = Pi into eval(diff(r(x), x), x = u). 

 

> l := t -> r(Pi) + subs(u=Pi,diff(r(u),u))*t:
'l(t)' = l(t);

helixPlot := spacecurve(r(t),t=-2*Pi..2*Pi,color=blue):
tangentPlot := spacecurve(l(t),t=-3..3,color=red):
display({helixPlot,tangentPlot},scaling=constrained,axes=boxed,viewpoint=circleleft);
 

 

l(t) = Vector[column](%id = 18446744078115413518)
Plot_2d
 

 

Next, let's compute the arc length function for the helix. [Remember that our parameter t ranges from -2π to 2π.] 

 

Note: Sometimes we have to tell Maple some extra information -- in this problem Maple should know that our dummy variable "u" is a real number. 

 

> assume(u::real):
arcLength := s = int(Norm(diff(r(u),u)),u=-2*Pi..t);
 

s = `*`(`^`(5, `/`(1, 2)), `*`(`+`(t, `*`(2, `*`(Pi))))) (10)
 

 

It's interesting to note that Maple's built in ArcLength function does not yield a useful formula for arc length here.  

 

> simplify(ArcLength(r(u),u=-2*Pi..t));
 

`+`(`-`(`*`(`+`(`*`(`/`(1, 2), `*`(I))), `*`(`^`(5, `/`(1, 2)), `*`(`+`(`*`(2, `*`(ln(sin(t)))), `*`(I, `*`(Pi)), `*`(2, `*`(ln(`/`(`*`(`+`(sin(t), `*`(I, `*`(signum(sin(t)), `*`(abs(cos(t))))))), `*`... (11)
 

 

The above formula is far more complicated than the one we originally derived. Oh well, Maple's not perfect. 

 

Substituting in 2π (the end of the curve) will give us the length of our helix. 

 

> simplify(subs(t=2*Pi,arcLength));
 

s = `+`(`*`(4, `*`(`^`(5, `/`(1, 2)), `*`(Pi)))) (12)
 

 

Now we can make Maple solve for t and then reparametrize our helix in terms of arc length. 

 

> reparametrize := t = solve(arcLength,t);
rArcLength := simplify(subs(reparametrize,r(t))):
'rArcLength' = rArcLength;

spacecurve(rArcLength,s=0..4*sqrt(5)*Pi,scaling=constrained,axes=boxed,viewpoint=circleleft);
 

 

 

 

Warning, solve may be ignoring assumptions on the input variables.
t = `+`(`-`(`*`(`/`(1, 5), `*`(`+`(`-`(s), `*`(2, `*`(`^`(5, `/`(1, 2)), `*`(Pi)))), `*`(`^`(5, `/`(1, 2)))))))
rArcLength = Vector[column](%id = 18446744078222360814)
Plot_2d
 

 

Of course, our graph looks no different, since we have the same curve (with a different parametrization).  

 

Now we can compute the curvature of the helix using the definition: "kappa = abs(VectorCalculus:-`*`(dT, `/`(1, `*`(ds))))". 

> T := diff(rArcLength,s);
 

Vector[column](%id = 18446744078222362254) (13)
 

 

Notice that we just computed the derivative of rArcLength and didn't bother dividing by it's length -- we don't need to since rArcLength is parametrized with respect to arc length! Don't believe me? Let's check the length of "T(s)" -- the unit tangent. 

 

> Norm(T);
 

1 (14)
 

 

Now we compute the curvature. 

 

> kappa := Norm(diff(T,s));
 

`/`(2, 5) (15)
 

 

We have re-discovered that the helix has constant curvature. 

 

Next, let's make Maple compute the TNB-frame for the helix. We can either do this "step-by-step" or using built in functions. Let's do it "step-by-step" first. 

 

> T := t -> diff(r(t),t)/Norm(diff(r(t),t)):
'T(t)' = T(t);

N := t -> diff(T(t),t)/Norm(diff(T(t),t)):
'N(t)' = N(t);

B := t -> simplify(T(t) &x N(t)):
'B(t)' = B(t);
 

 

 

T(t) = Vector[column](%id = 18446744078222363574)
N(t) = Vector[column](%id = 18446744078222357198)
B(t) = Vector[column](%id = 18446744078222359838) (16)
 

 

Now let's use the built in function "TNBFrame". 

 

> TNBFrame(r(t),t);

T := t -> subs(u=t,simplify(TNBFrame(r(u),u)[1])):
'T(t)' = T(t);

N := t -> subs(u=t,simplify(TNBFrame(r(u),u)[2])):
'N(t)' = N(t);

B := t -> subs(u=t,simplify(TNBFrame(r(u),u)[3])):
'B(t)' = B(t);
 

 

 

 

Vector[column](%id = 18446744078222354782), Vector[column](%id = 18446744078222355022), Vector[column](%id = 18446744078222355262)
T(t) = Vector[column](%id = 18446744078222350686)
N(t) = Vector[column](%id = 18446744078222344430)
B(t) = Vector[column](%id = 18446744078222346590) (17)
 

 

We can also use a built in command to compute curvature. 

 

> kappa := simplify(Curvature(r(t),t));
 

`/`(2, 5) (18)
 

 

Let's plot the TNB-frame for our helix at the point t = Pi. 

 

> helixPlot := spacecurve(r(t),t=-2*Pi..2*Pi,color=black):
TPlot := arrow(r(Pi),T(Pi),shape=arrow,color=blue):
NPlot := arrow(r(Pi),N(Pi),shape=arrow,color=green):
BPlot := arrow(r(Pi),B(Pi),shape=arrow,color=red):
display({helixPlot,TPlot,NPlot,BPlot},scaling=constrained,axes=boxed,viewpoint=circleleft);
 

Plot_2d
 

 

A curve in `*`(`^`(real, 3)) doesn't neccessarily lie in a plane -- see for example the helix above! Given a particular point on the curve, the osculating plane at that point is the best try at placing the curve in a plane. In other words, near the point in question, the curve 

looks like it lies in the osculating plane. The osculating plane for r(t) at t = t[0] is the plane which passes through the point r(t[0])and has normal vector B(t[0]). We will plot the helix together with its osculating point at t = Pi. 

 

> oscPlane := B(Pi).(<x,y,z>-r(Pi))=0;

oscPlot := plot3d(solve(oscPlane,z),x=-2..2,y=-2..3):
pointPlot := pointplot3d(r(Pi),symbol=sphere,symbolsize=10,color=red):
display({oscPlot,pointPlot,helixPlot},scaling=constrained,axes=boxed,viewpoint=circleleft);
 

 

`+`(`*`(`/`(1, 5), `*`(`^`(5, `/`(1, 2)), `*`(sin(Pi), `*`(`+`(x, 2))))), `-`(`*`(`/`(1, 5), `*`(`^`(5, `/`(1, 2)), `*`(cos(Pi), `*`(y))))), `*`(`/`(2, 5), `*`(`^`(5, `/`(1, 2)), `*`(`+`(z, `-`(Pi))))...
Plot_2d
 

 

We know that tangent lines give the best linear approximation of a curve. The osculating circle gives the best approximating circle. That is, the osculating circle at a particular point looks like the curve near that point. The osculating circle lies in the osculating plane, touches the curve at the point in question, and has a raduis of `/`(1, `*`(kappa)) (the reciprical of the curvature at that point). Let's graph the osculating circle for the helix for t = Pi. 

> oscCircle := t -> cos(theta)/kappa * T(t) + sin(theta)/kappa * N(t) + (1/kappa * N(t) + r(t)):
'C(t)' = oscCircle(t);

oscPlot := spacecurve(oscCircle(Pi),theta=0..2*Pi,color=blue):
display({oscPlot,helixPlot,pointPlot},scaling=constrained,axes=boxed,viewpoint=circleleft);
 

 

C(t) = Vector[column](%id = 18446744078222322374)
Plot_2d
 

 

The curvature function measures how curved our curve is. Another function called the "torsion" function measures how much the curve "twists" out of its osculating plane. Torsion is defined to be the function tau(s)where eval(diff(B(x), x), x = s) = VectorCalculus:-`-`(VectorCalculus:-`*`(tau(s), N(s))). So to compute torsion directly we would need to parametrize our curve with respect to arc length, compute the curve's TNB-frame, and then differentiate the binormal vector. This is too much work. So in the same way we found a direct formula for curvature, we get a direct formula for torsion: 

 

tau(t) = VectorCalculus:-`*`(Typesetting:-delayDotProduct(Typesetting:-delayCrossProduct(eval(diff(r(x), x), x = t), eval(diff(r(x), x, x), x = t)), eval(diff(r(x), x, x, x), x = t)), `/`(1, `*`(`^`(a... 

 

Let's compute the torsion of the helix using this formula. 

 

> tau := t -> simplify(((diff(r(t),t) &x diff(r(t),t$2)).diff(r(t),t$3))/(Norm(diff(r(t),t) &x diff(r(t),t$2))^2)):
'tau(t)' = tau(t);
 

tau(t) = `/`(1, 5) (19)
 

 

So we see that the helix not only has constant curvature, but also constant torsion. This means it is "twisted" the "same" way everywhere. Notice if the torsion is 0, then eval(diff(B(x), x), x = t) = 0, so the binormal is constant. This in turn implies that the osculating plane is the same at all points so we have a planar curve. In fact, a curve lies in a plane if and only if tau(t) = 0.  

 

Note: There is a built in function which computes torsion. 

 

> simplify(Torsion(r(t),t));
 

`/`(1, 5) (20)
 

 

Example: We can parametrize the ellipse VectorCalculus:-`+`(VectorCalculus:-`*`(`*`(`^`(x, 2)), `/`(1, `*`(`^`(3, 2)))), VectorCalculus:-`*`(`*`(`^`(y, 2)), `/`(1, `*`(`^`(1, 2))))) = 1 using sines and cosines as follows: x(t) = VectorCalculus:-`*`(3, cos(theta)), y(t) = sin(theta), and z(t) = 0 where `and`(`<=`(0, theta), `<=`(theta, VectorCalculus:-`*`(2, Pi))). Let's define a vector valued function called "r[1]" so that the graph of r[1](t) is this ellipse. Then let's compute its arc length and TNB-frame. 

 

> r[1] := t -> <3*cos(t),1*sin(t),0>:
'r[1](t)' = r[1](t);

s := t -> int(Norm(diff(r[1](u),u)),u=0..t):
's(t)' = s(t);

arcLength := simplify(s(2*Pi))=evalf(s(2*Pi));

ellipseFrame := TNBFrame(r[1](t),t):
T[1] := simplify(ellipseFrame[1]);
N[1] := simplify(ellipseFrame[2]);
B[1] := simplify(ellipseFrame[3]);
 

 

 

 

 

 

r[1](t) = Vector[column](%id = 18446744078248663630)
s(t) = `+`(`*`(3, `*`(EllipticE(`+`(`*`(`/`(2, 3), `*`(`^`(2, `/`(1, 2)))))))), `-`(`*`(3, `*`(EllipticE(cos(t), `+`(`*`(`/`(2, 3), `*`(`^`(2, `/`(1, 2))))))))))
`+`(`*`(12, `*`(EllipticE(`+`(`*`(`/`(2, 3), `*`(`^`(2, `/`(1, 2))))))))) = 13.36489322
Vector[column](%id = 18446744078248644966)
Vector[column](%id = 18446744078248645326)
Vector[column](%id = 18446744078248645566) (21)
 

 

Next, let's plot the ellipse together with its TNB-frame at the point t = VectorCalculus:-`*`(Pi, `/`(1, 2)). 

 

> ellipsePlot := spacecurve(r[1](t),t=0..2*Pi,color=black):
TPlot := arrow(r[1](Pi/2),subs(t=Pi/2,T[1]),shape=arrow,color=blue):
NPlot := arrow(r[1](Pi/2),subs(t=Pi/2,N[1]),shape=arrow,color=green):
BPlot := arrow(r[1](Pi/2),subs(t=Pi/2,B[1]),shape=arrow,color=red):
display({ellipsePlot,TPlot,NPlot,BPlot},scaling=constrained,axes=boxed,viewpoint=circleleft);
 

Plot_2d
 

 

Now let's graph the curvature function kappa(t) for `and`(`<=`(0, t), `<=`(t, VectorCalculus:-`*`(2, Pi))). 

 

> plot(Curvature(r[1](t),t),t=0..2*Pi);
 

Plot_2d
 

 

Next, let's compute the torsion function for the ellipse. Notice that is it zero. So the derivative of the binormal should be the zero vector. So we'll also compute that derivative. 

 

> Torsion(r[1](t),t);
 

0 (22)
 

> diff(B[1],t);
 

Vector[column](%id = 18446744078248619054) (23)
 

 

The torsion is zero since the ellipse's osculating plane is the same for every value of t -- this means our curve is not "twisting" out of the osculating plane. In other words, the torsion is zero because our curve lies in the xy-plane. In fact, it is true that any curve lying in a plane will have zero torsion. 

 

 

Example: Consider the twisted cubic given by the following parametric equations:  x(t) = t, y(t) = `*`(`^`(t, 2)), and z(t) = `*`(`^`(t, 3)) where `and`(`<=`(0, t), `<=`(t, 2)). Let's compute its arc length, curvature, and TNB-frame. 

 

> r := t -> <t,t^2,t^3>:
'r(t)' = r(t);

s := t -> int(Norm(diff(r(u),u)),u=0..t):
's(t)' = s(t);

arcLength := simplify(s(2))=evalf(s(2));

ellipseFrame := TNBFrame(r(t),t):
T := simplify(ellipseFrame[1]);
N := simplify(ellipseFrame[2]);
B := simplify(ellipseFrame[3]);
 

 

 

 

 

 

r(t) = Vector[column](%id = 18446744078248619294)
s(t) = `+`(`/`(`*`(`/`(1, 3), `*`(`+`(`*`(2, `*`(t, `*`(`^`(`+`(`-`(2), `*`(I, `*`(`^`(5, `/`(1, 2))))), `/`(1, 2))))), `*`(8, `*`(`^`(t, 3), `*`(`^`(`+`(`-`(2), `*`(I, `*`(`^`(5, `/`(1, 2))))), `/`(1...
s(t) = `+`(`/`(`*`(`/`(1, 3), `*`(`+`(`*`(2, `*`(t, `*`(`^`(`+`(`-`(2), `*`(I, `*`(`^`(5, `/`(1, 2))))), `/`(1, 2))))), `*`(8, `*`(`^`(t, 3), `*`(`^`(`+`(`-`(2), `*`(I, `*`(`^`(5, `/`(1, 2))))), `/`(1...
s(t) = `+`(`/`(`*`(`/`(1, 3), `*`(`+`(`*`(2, `*`(t, `*`(`^`(`+`(`-`(2), `*`(I, `*`(`^`(5, `/`(1, 2))))), `/`(1, 2))))), `*`(8, `*`(`^`(t, 3), `*`(`^`(`+`(`-`(2), `*`(I, `*`(`^`(5, `/`(1, 2))))), `/`(1...
s(t) = `+`(`/`(`*`(`/`(1, 3), `*`(`+`(`*`(2, `*`(t, `*`(`^`(`+`(`-`(2), `*`(I, `*`(`^`(5, `/`(1, 2))))), `/`(1, 2))))), `*`(8, `*`(`^`(t, 3), `*`(`^`(`+`(`-`(2), `*`(I, `*`(`^`(5, `/`(1, 2))))), `/`(1...
`+`(`/`(`*`(`/`(2, 483), `*`(`^`(161, `/`(1, 2)), `*`(`+`(`*`(322, `*`(`^`(`+`(`-`(2), `*`(I, `*`(`^`(5, `/`(1, 2))))), `/`(1, 2)))), `*`(`*`(161, `*`(I)), `*`(`^`(`+`(`-`(2), `*`(I, `*`(`^`(5, `/`(1,...
`+`(`/`(`*`(`/`(2, 483), `*`(`^`(161, `/`(1, 2)), `*`(`+`(`*`(322, `*`(`^`(`+`(`-`(2), `*`(I, `*`(`^`(5, `/`(1, 2))))), `/`(1, 2)))), `*`(`*`(161, `*`(I)), `*`(`^`(`+`(`-`(2), `*`(I, `*`(`^`(5, `/`(1,...
`+`(`/`(`*`(`/`(2, 483), `*`(`^`(161, `/`(1, 2)), `*`(`+`(`*`(322, `*`(`^`(`+`(`-`(2), `*`(I, `*`(`^`(5, `/`(1, 2))))), `/`(1, 2)))), `*`(`*`(161, `*`(I)), `*`(`^`(`+`(`-`(2), `*`(I, `*`(`^`(5, `/`(1,...
`+`(`/`(`*`(`/`(2, 483), `*`(`^`(161, `/`(1, 2)), `*`(`+`(`*`(322, `*`(`^`(`+`(`-`(2), `*`(I, `*`(`^`(5, `/`(1, 2))))), `/`(1, 2)))), `*`(`*`(161, `*`(I)), `*`(`^`(`+`(`-`(2), `*`(I, `*`(`^`(5, `/`(1,...
Vector[column](%id = 18446744078222367670)
Vector[column](%id = 18446744078222367790)
Vector[column](%id = 18446744078222368270) (24)
 

 

Next, let's graph the curvature and the torsion in the same plot window. From this we can see that the twisted cubic gets less curved and less twisted as proc (t) options operator, arrow; infinity end proc. 

 

> plot({Curvature(r(t),t),Torsion(r(t),t)},t=0..2);
 

Plot_2d
 

 

Now let's graph the twisted cubic along with its osculating circle and TNB-frame at t = 1. 

 

> cubicFrame := TNBFrame(r(t),t):
T1 := subs(t=1,cubicFrame[1]):
N1 := subs(t=1,cubicFrame[2]):
B1 := subs(t=1,cubicFrame[3]):

kappa1 := subs(t=1,Curvature(r(t),t)):
oscCircle := cos(theta)/kappa1*T1 + sin(theta)/kappa1*N1 + 1/kappa1*N1+r(1):

cubicPlot := spacecurve(r(t),t=0..2,color=black):
TPlot := arrow(r(1),T1,shape=arrow,color=blue):
NPlot := arrow(r(1),N1,shape=arrow,color=green):
BPlot := arrow(r(1),B1,shape=arrow,color=red):
oscPlot := spacecurve(oscCircle,theta=0..2*Pi,color=grey):
display({cubicPlot,TPlot,NPlot,BPlot,oscPlot},scaling=constrained,axes=boxed,viewpoint=circleleft);
 

Plot_2d
 

 

Finally, let's graph the twisted cubic along with its osculating plane at t = 1. 

 

> oscPlane := B1.(<x,y,z>-r(1))=0;

oscPlanePlot := plot3d(solve(oscPlane,z),x=0..2,y=0..4):
cubicPlot := spacecurve(r(t),t=0..2,color=black,thickness=3):
display({oscPlanePlot,cubicPlot},axes=boxed,orientation=[-150,70],viewpoint=circleleft);
 

 

`+`(`*`(`/`(3, 19), `*`(`^`(19, `/`(1, 2)), `*`(`+`(x, `-`(1))))), `-`(`*`(`/`(3, 19), `*`(`^`(19, `/`(1, 2)), `*`(`+`(y, `-`(1)))))), `*`(`/`(1, 19), `*`(`^`(19, `/`(1, 2)), `*`(`+`(z, `-`(1)))))) = ...
Plot_2d
 

 

Example: Consider the curve parametrized by 

 

> r := t -> <(2*cos(7*t)+5)*cos(t),(2*cos(7*t)+5)*sin(t),2*sin(7*t)>:
'r(t)' = r(t);
 

r(t) = Vector[column](%id = 18446744078248664830) (25)
 

 

where  

 

First, we'll plot this curve. 

 

> spacecurve(r(t),t=0..2*Pi,scaling=constrained,numpoints=5000,color=blue,thickness=3,axes=boxed,viewpoint=circleleft);
 

Plot_2d
 

 

Next, let's compute its arc length and plot its curvature. 

 

Since Maple cannot find an exact arc length, we'll use "evalf" to get a decimal approximation. 

 

> "Arc Length" = evalf(ArcLength(r(t),t=0..2*Pi));

plot(Curvature(r(t)),t=0..2*Pi);
 

 

Arc Length
Plot_2d
 

 

The following commands compute the TNB-frame of our curve for values of  t ranging from 0 to 2π. Then the second group of commands plots these vectors along with the curve. [I will plot n = 40sets of TNB-vectors. If you would like to plot more or less, just modify the value of n.] 

 

> TNBf := TNBFrame(r(t)):

n := 40:  # The number of triples of vectors to plot.

T := [seq(0,i=1..n)]: N := T: B := T:  # T,N,B are initially arrays of zeros.

# As i = 1, 2, ..., n, we substitute in t = 2Pi/n, 4Pi/n, ... 2n Pi/n = 2Pi.
for i from 1 to n do
  T[i] := simplify(subs(t=2.0*Pi*(i/n),TNBf[1]));
  N[i] := simplify(subs(t=2.0*Pi*(i/n),TNBf[2]));
  B[i] := simplify(subs(t=2.0*Pi*(i/n),TNBf[3]));
end do:

crv := spacecurve(r(t),t=0..2*Pi,color=gray,thickness=3):
Tplot := [seq(0,i=1..n)]: Nplot := Tplot: Bplot := Tplot:
for i from 1 to n do
  Tplot[i] := arrow(r(2.0*Pi*(i/n)),T[i],shape=arrow,color=green):
  Nplot[i] := arrow(r(2.0*Pi*(i/n)),N[i],shape=arrow,color=red):
  Bplot[i] := arrow(r(2.0*Pi*(i/n)),B[i],shape=arrow,color=blue):
end do:
display({crv,seq(op([Tplot[i],Nplot[i],Bplot[i]]),i=1..n)},scaling=constrained,axes=boxed,viewpoint=circleleft);
 

Plot_2d
 

> TNBf := TNBFrame(r(t)):

n := 100:  # The number of triples of vectors to plot.

T := [seq(0,i=1..n)]: N := T: B := T:  # T,N,B are initially arrays of zeros.

# As i = 1, 2, ..., n, we substitute in t = 2Pi/n, 4Pi/n, ... 2n Pi/n = 2Pi.
for i from 1 to n do
  T[i] := simplify(subs(t=2.0*Pi*(i/n),TNBf[1]));
  N[i] := simplify(subs(t=2.0*Pi*(i/n),TNBf[2]));
  B[i] := simplify(subs(t=2.0*Pi*(i/n),TNBf[3]));
end do:

crv := spacecurve(r(t),t=0..2*Pi,color=gray,thickness=3,numpoints=5000):
Tplot := [seq(0,i=1..n)]: Nplot := Tplot: Bplot := Tplot: myFrame := Tplot:
for i from 1 to n do
  Tplot[i] := arrow(r(2.0*Pi*(i/n)),T[i],shape=arrow,color=green):
  Nplot[i] := arrow(r(2.0*Pi*(i/n)),N[i],shape=arrow,color=red):
  Bplot[i] := arrow(r(2.0*Pi*(i/n)),B[i],shape=arrow,color=blue):
  myFrame[i] := display({crv,Tplot[i],Nplot[i],Bplot[i]}):
end do:
display(seq(myFrame[i],i=1..n),insequence=true,scaling=constrained,axes=boxed,viewpoint=circleright);
 

Plot_2d
 

 

Example: Consider the following vector valued function: (where `and`(`<=`(0, t), `<=`(t, VectorCalculus:-`*`(4, Pi)))) 

      

> r := t -> <2*sqrt(t)*cos(t),sqrt(t)*sin(t),t>:
'r(t)' = r(t);

spacecurve(r(t),t=0..4*Pi,color=blue,thickness=3,axes=boxed,viewpoint=circleleft);
 

 

r(t) = Vector[column](%id = 18446744078210275678)
Plot_2d
 

 

First, let's compute r'(t), |r'(t)|, and the curve's arc length (using "evalf" to get a decimal approximation). 

 

> diff(r(t),t);
Norm(diff(r(t),t));

s := t -> int(Norm(diff(r(u),u)),u=0..t):
's(t)' = s(t);

s(4*Pi) = evalf(s(4*Pi));
 

 

 

 

Vector[column](%id = 18446744078210276518)
`+`(`*`(`/`(1, 2), `*`(`^`(`+`(`-`(`/`(`*`(`+`(`-`(`*`(4, `*`(t))), `-`(`*`(3, `*`(`^`(cos(t), 2)))), `*`(12, `*`(cos(t), `*`(t, `*`(sin(t))))), `-`(`*`(16, `*`(`^`(t, 2)))), `*`(12, `*`(`^`(t, 2), `*...
s(t) = int(`+`(`*`(`/`(1, 2), `*`(`^`(`+`(`-`(`/`(`*`(`+`(`-`(`*`(4, `*`(u))), `-`(`*`(3, `*`(`^`(cos(u), 2)))), `*`(12, `*`(cos(u), `*`(u, `*`(sin(u))))), `-`(`*`(16, `*`(`^`(u, 2)))), `*`(12, `*`(`^...
int(`+`(`*`(`/`(1, 2), `*`(`^`(`+`(`-`(`/`(`*`(`+`(`-`(`*`(4, `*`(u))), `-`(`*`(3, `*`(`^`(cos(u), 2)))), `*`(12, `*`(cos(u), `*`(u, `*`(sin(u))))), `-`(`*`(16, `*`(`^`(u, 2)))), `*`(12, `*`(`^`(u, 2)... (26)
 

 

...OR... 

 

> evalf(ArcLength(r(t),t=0..4*Pi));
 

49.16183756 (27)
 

 

The following commands compute the unit tangents, normals, and binormals for this curve and then plots them. 

 

> TNBf := TNBFrame(r(t)):

n := 30:  # The number of triples of vectors to plot.

T := [seq(0,i=1..n)]: N := T: B := T:  # T,N,B are initially arrays of zeros.

# As i = 1, 2, ..., n, we substitute in t = 4Pi/n, 8Pi/n, ... 4n Pi/n = 4Pi.
for i from 1 to n do
  T[i] := simplify(subs(t=4.0*Pi*(i/n),TNBf[1]));
  N[i] := simplify(subs(t=4.0*Pi*(i/n),TNBf[2]));
  B[i] := simplify(subs(t=4.0*Pi*(i/n),TNBf[3]));
end do:

crv := spacecurve(r(t),t=0..4*Pi,color=gray,thickness=3):
Tplot := [seq(0,i=1..n)]: Nplot := Tplot: Bplot := Tplot:
for i from 1 to n do
  Tplot[i] := arrow(r(4.0*Pi*(i/n)),T[i],shape=arrow,color=green):
  Nplot[i] := arrow(r(4.0*Pi*(i/n)),N[i],shape=arrow,color=red):
  Bplot[i] := arrow(r(4.0*Pi*(i/n)),B[i],shape=arrow,color=blue):
end do:
display({crv,seq(op([Tplot[i],Nplot[i],Bplot[i]]),i=1..n)},scaling=constrained,axes=boxed,viewpoint=circleleft);
 

Plot_2d
 

 

Now let's find and plot the curvature of r(t).  

 

> kappa := simplify(Curvature(r(t)));

plot(kappa,t=0..4*Pi);
 

 

`+`(`/`(`*`(2, `*`(`^`(`/`(`*`(`+`(`*`(48, `*`(`^`(cos(t), 2), `*`(`^`(t, 4)))), `-`(`*`(24, `*`(`^`(t, 2), `*`(`^`(cos(t), 2))))), `*`(3, `*`(`^`(cos(t), 2))), `*`(96, `*`(`^`(t, 3), `*`(cos(t), `*`(...
`+`(`/`(`*`(2, `*`(`^`(`/`(`*`(`+`(`*`(48, `*`(`^`(cos(t), 2), `*`(`^`(t, 4)))), `-`(`*`(24, `*`(`^`(t, 2), `*`(`^`(cos(t), 2))))), `*`(3, `*`(`^`(cos(t), 2))), `*`(96, `*`(`^`(t, 3), `*`(cos(t), `*`(...
`+`(`/`(`*`(2, `*`(`^`(`/`(`*`(`+`(`*`(48, `*`(`^`(cos(t), 2), `*`(`^`(t, 4)))), `-`(`*`(24, `*`(`^`(t, 2), `*`(`^`(cos(t), 2))))), `*`(3, `*`(`^`(cos(t), 2))), `*`(96, `*`(`^`(t, 3), `*`(cos(t), `*`(...
`+`(`/`(`*`(2, `*`(`^`(`/`(`*`(`+`(`*`(48, `*`(`^`(cos(t), 2), `*`(`^`(t, 4)))), `-`(`*`(24, `*`(`^`(t, 2), `*`(`^`(cos(t), 2))))), `*`(3, `*`(`^`(cos(t), 2))), `*`(96, `*`(`^`(t, 3), `*`(cos(t), `*`(...
`+`(`/`(`*`(2, `*`(`^`(`/`(`*`(`+`(`*`(48, `*`(`^`(cos(t), 2), `*`(`^`(t, 4)))), `-`(`*`(24, `*`(`^`(t, 2), `*`(`^`(cos(t), 2))))), `*`(3, `*`(`^`(cos(t), 2))), `*`(96, `*`(`^`(t, 3), `*`(cos(t), `*`(...
`+`(`/`(`*`(2, `*`(`^`(`/`(`*`(`+`(`*`(48, `*`(`^`(cos(t), 2), `*`(`^`(t, 4)))), `-`(`*`(24, `*`(`^`(t, 2), `*`(`^`(cos(t), 2))))), `*`(3, `*`(`^`(cos(t), 2))), `*`(96, `*`(`^`(t, 3), `*`(cos(t), `*`(...
`+`(`/`(`*`(2, `*`(`^`(`/`(`*`(`+`(`*`(48, `*`(`^`(cos(t), 2), `*`(`^`(t, 4)))), `-`(`*`(24, `*`(`^`(t, 2), `*`(`^`(cos(t), 2))))), `*`(3, `*`(`^`(cos(t), 2))), `*`(96, `*`(`^`(t, 3), `*`(cos(t), `*`(...
`+`(`/`(`*`(2, `*`(`^`(`/`(`*`(`+`(`*`(48, `*`(`^`(cos(t), 2), `*`(`^`(t, 4)))), `-`(`*`(24, `*`(`^`(t, 2), `*`(`^`(cos(t), 2))))), `*`(3, `*`(`^`(cos(t), 2))), `*`(96, `*`(`^`(t, 3), `*`(cos(t), `*`(...
Plot_2d
 

 

Example: Consider the graph of y = ln(x) for `>`(x, .1). 

      

> f := x -> ln(x):
'f(x)' = f(x);
plot(f(x),x=0.1..5);
 

 

f(x) = ln(x)
Plot_2d
 

 

Let's compute the arc length of y = ln(x) for `and`(`<=`(1, x), `<=`(x, 5)). The most natural parametrization for this graph is x = x and y = ln(x) where `and`(`<=`(1, x), `<=`(x, 5)). In vector valued form this is r(x) = `<,>`(x, f(x)). 

 

> Int(sqrt(1+(diff(f(x),x))^2),x=1..5) = ArcLength(<x,f(x)>,x=1..5);

"Arc Length" = evalf(ArcLength(<x,f(x)>,x=1..5));
 

 

Int(`*`(`^`(`+`(1, `/`(1, `*`(`^`(x, 2)))), `/`(1, 2))), x = 1 .. 5) = `+`(`-`(`*`(`^`(2, `/`(1, 2)))), arctanh(`+`(`*`(`/`(1, 2), `*`(`^`(2, `/`(1, 2)))))), `*`(`^`(2, `/`(1, 2)), `*`(`^`(13, `/`(1, ...
Arc Length (28)
 

 

Next, let's find the curvature of y = ln(x) and plot it for `and`(`<=`(.1, x), `<=`(x, 5)). We can use Maple's "Curvature" function or our special formula for the curvature of a graph of a function. Both of these answers are equivalent, but the special formula yields a simpler answer. 

 

> "Built in curvature function" = Curvature(<x,f(x)>,x);

"Special 2D formula for curvature" = abs(diff(f(x),x,x))/(1+(diff(f(x),x))^2)^(3/2);

kappa := Curvature(<x,f(x)>,x):
plot(kappa, x=0.1..5);
 

 

 

Built in curvature function
Built in curvature function
Special 2D formula for curvature
Plot_2d
 

 

Where is the curvature of y = ln(x) maximized?  We should look for critical points (where the derivative of the curvature function is 0). 

 

> simplify(diff(kappa,x));
 

`+`(`-`(`/`(`*`(`+`(`*`(2, `*`(`^`(x, 2))), `-`(1)), `*`(csgn(`/`(1, `*`(`+`(`*`(`^`(x, 2)), 1)))))), `*`(`^`(`/`(`*`(`+`(`*`(`^`(x, 2)), 1)), `*`(`^`(x, 2))), `/`(1, 2)), `*`(`^`(`+`(`*`(`^`(x, 2)), ... (29)
 

 

Interestingly, if we attempt to solve the unsimplified form of diff(kappa(x), x) = 0, Maple fails to find any solutions. However, if we simplify and then solve, Maple finds 2 critical points (we are interested in the positive one). 

 

> solve(diff(kappa,x)=0);
 

`+`(`*`(`/`(1, 2), `*`(`^`(2, `/`(1, 2))))), `+`(`-`(`*`(`/`(1, 2), `*`(`^`(2, `/`(1, 2)))))) (30)
 

> solve(simplify(diff(kappa,x)=0));
 

`+`(`*`(`/`(1, 2), `*`(`^`(2, `/`(1, 2))))), `+`(`-`(`*`(`/`(1, 2), `*`(`^`(2, `/`(1, 2)))))) (31)
 

 

Alternatively, we can use "fsolve" to numerically solve (looking for an approximate answer). However, "fsolve" (using the default guess "x=0") picks the "wrong" solution. We need to give it some help and suggest that the solution we want is close to x = 1. 

 

> fsolve(simplify(diff(kappa,x))=0);
 

-.7071067812 (32)
 

> fsolve(diff(kappa,x)=0,x=1);
 

.7071067812 (33)
 

 

The curvature is maximized (on the interval `and`(`<=`(.1, x), `<=`(x, 5))) at about x = .7071067812 (the exact answer is x = 1/sqrt(2)).