# Determine unit outward normal vector for a curve

It is necessary for me to find the unit outward normal vector for the curve:

$$\gamma=(x(t),y(t))$$

where $$x(t)=\cos(t)−0.5\cos(3t)$$ and $$y(t)=\sin(t)+\sin(7t)+\sin(3t)$$ I know how to find unit outward normal vector for this: using

$$T=\frac{\gamma' (t)}{||\gamma(t)||}$$ so $$N=\frac{T (t)}{||T(t)|| }$$

but my problem is that I do not have $t$ . I just have $x(t)$ and $y(t)$. How could I find $t$ or $N$ without knowing $t$.

Is there any command in MATLAB or MAPLE to this?

All the info you need can be found by reading about the Frenet (or TNB, Tangent-Normal-Binormal) frame.

Using the notation on the Wikipedia page, you can denote your curve as $$\vec{r}(s) = (x(s),y(s),0)$$ and the tangent and normal vectors are given by $$\vec{T} = \dfrac{d\vec{r}}{ds}$$ and $$\vec{N} = \dfrac{d\vec{T}}{ds}\left/\left|\left|\dfrac{d\vec{T}}{ds}\right|\right|\right.,$$ where $s$ represents arc length. Since you are restricted to 2D instead of 3D, the binormal vector is just $\pm\bf\hat{k}$.

The normal vector $\vec{N}$ always points to the interior of the curve (the direction of normal acceleration if you're moving along the curve), so the vector you want is actually given by $-\vec{N}$.

I'm not quite sure what you mean by the statement "I do not have $t$. I just have $x(t)$ and $y(t)$." The normal vector will be different at different points along your curve. You can write a general expression for $\vec{N}(t)$ or you can pick a specific value for $t$ and get a unique $\vec{N}$. Also, since your independent variable, $t$, is not arc length you will have to compute $\vec{T}$ using the chain rule as $$\vec{T} = \dfrac{d\vec{r}}{dt}\left/\dfrac{ds}{dt}\right..$$

There is an analytical formula for arc length of a parametrically defined curve $$s = \int_{t_0}^t \sqrt{x'(t^*)^2+y'(t^*)^2} dt^*$$ Or, if you have $x$ and $y$ defined as a set of discrete points along the curve as $x=\{x_1, x_2, x_3, ...\}$, $y=\{y_1, y_2, y_3, ...\}$ you could estimate the tangent and normal vectors using (for example) finite differences.

An analytical expression for the parameterization you have given will be complicated. A good alternative might be to pick a bunch of (closely spaced) points on your curve to discretize the problem and then use something like this Frenet coordinate routine from the MATLAB File Exchange.

I implemented this real quick using finite differences as suggested by @DougLipinski, and this is what I come up with, at first glance it looks correct. Green vectors are the tangent vectors and red are the normals.

To calculate the differential arc length I used this relationship $$(ds)^2 = (dx)^2 + (dy)^2$$ and applied a simple first order finite difference to $x$ and $y$.

Here's the code, let me know if you see anything wrong

clear all
close all

t = 0:0.01:(2*pi+0.01);
t = t(:);
n = length(t);
x = cos(t) - 0.5*cos(3*t);
y = sin(t) + sin(7*t) + sin(3*t);

e = ones(n,1);
A = 0.5*spdiags([-e e],[-1,1],n,n);%first order FD stencil

dx = A*x;
dy = A*y;

ds = sqrt(dx.^2 + dy.^2);

T = [dx./ds  dy./ds];
for rr = 1:size(T,1)
T(rr,:) = T(rr,:)/sqrt(T(rr,1)^2 + T(rr,2)^2);
end
dT  = [A*T(:,1) A*T(:,2)];

N   = [dT(:,1)./ds dT(:,2)./ds];
for rr = 1:size(N,1)
N(rr,:) = N(rr,:)/sqrt(N(rr,1)^2 + N(rr,2)^2);
end

figure
plot(x,y)
hold on
quiver(x,y,T(:,1),T(:,2))
quiver(x,y,N(:,1),N(:,2))

• Definitely not quite right. Your tangent (green) vectors are not unit vectors so the red vectors are not normal to the curve since they account for the changing length of T as well as the changing direction. – Doug Lipinski Dec 10 '14 at 18:52
• They weren't unit vectors because I was normalizing them wrong, I corrected that, but something still seems off. Anything obvious to you? – user7257 Dec 10 '14 at 19:24
• Your code looks ok to me now. I would do the normalization for T (and N) as T = [dx./ds dy./ds]; normT = sqrt(sum(T.^2,2)); T = bsxfun(@rdivide,T,normT); but loops make it more clear what's going on. – Doug Lipinski Dec 10 '14 at 21:20
• @DougLipinski Any idea what the speeds up are using bsxfun over loops? – user7257 Dec 11 '14 at 14:37
• It depends on the loop. In some cases (i.e. if the just-in-time compiler does a good job with the loop) there may not be much difference. In this code the loops don't take much time anyway. However, if you use a lot more points you will start to see a difference. Using 10,000x more points on my machine your loop takes a factor of ~40x as long as calling T = bsxfun(@rdivide,T,sqrt(sum(T.^2,2)));. Things are even faster (~70x speedup) using normT = sqrt(T(:,1).^2+T(:,2).^2); T(:,1) = T(:,1)./normT; T(:,2) = T(:,2)./normT;. – Doug Lipinski Dec 11 '14 at 15:30