Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I want to draw a series of normals to a curve, where the curve has been parametrized by a single angle, i.e., the polar angle. The curve is actually sinusoidal perturbation of a circle of radius 1/2, and the magnitude of the perturbation is given by amp.

I have the normal function calculated in the code below already. I want to be able to draw normals to the curve at different points on the curve. How do I do this?

orad       = 1/2;
amp        = 0.05;
numpetals  = 7; 

(*Polar information of interface*)
r[th_]  := orad + amp * Sin[numpetals*th];
rp[th_] := amp*numpetals*Cos[numpetals*th];

(*Cartesian information of interface*)
x[th_]  := r[th]*Cos[th]; (*X-coordinate of the interface/*)
y[th_]  := r[th]*Sin[th]; (*Y-coordinate of the interface*)

(*Speeds of traveral*)
xp[th_] := rp[th]*Cos[th] - r[th]*Sin[th];
yp[th_] := rp[th]*Sin[th] + r[th]*Cos[th];

(*Outward unit normal to the curve*)
normal[th_] := {yp[th], -xp[th]}/Sqrt[xp[th]^2 + yp[th]^2];
share|improve this question
look at this related Q&A. – Kuba Jul 7 '13 at 16:32
up vote 4 down vote accepted

A solution using PolarPlot.

normalArrows = Table[Arrow[{{x[th], y[th]}, {x[th], y[th]} + 0.1 normal[th]}], {th,
 0, 360 \[Degree], 4 \[Degree]}];
PolarPlot[r[th], {th, 0, 360 \[Degree]}, Epilog -> normalArrows, PlotRange -> 0.65]

enter image description here

share|improve this answer
Alternatively: normalArrows = Table[Arrow[TranslationTransform[{x[θ], y[θ]}] /@ {{0, 0}, - 0.1 Cross[Normalize[{x'[θ], y'[θ]}]]}], {θ, 0, 360 °, 4 °}]. – J. M. Oct 16 '15 at 18:08
Cool. With descriptive function names this makes things very instructive. – Suba Thomas Oct 19 '15 at 15:40

If I redefine normal, it is easy to plot the curve and its normals.

orad = 1/2;
amp = 0.05;
numpetals = 7;

r[th_] := orad + amp*Sin[numpetals*th]
rp[th_] := amp*numpetals*Cos[numpetals*th]

x[th_] := r[th]*Cos[th]; 
y[th_] := r[th]*Sin[th];

xp[th_] := rp[th]*Cos[th] - r[th]*Sin[th]
yp[th_] := rp[th]*Sin[th] + r[th]*Cos[th]

normal[th_] := Module[{unit, nx, ny},
  unit = Normalize@{xp[th], yp[th]};
  nx = unit[[2]]; ny = -unit[[1]];
  {{x[t], y[t]}, {x[t], y[t]} + {nx, ny}}]

Framed @ ParametricPlot[{x[u], y[u]}, {u, 0., 360 °},
  Epilog -> Table[Line[normal[t]], {t, 0., 360 °, 45 °}], 
  PlotRange -> 1.5]


share|improve this answer

Same approach (ParametricPlot, Epilog) as m_goldberg but with your definition for the normal.

points = Table[th, {th, -Pi, Pi, Pi/4}]
 {x[th], y[th]},
 {th, -Pi, Pi},
 Epilog -> {
   Point[{x[#], y[#]} & /@ points],
       {x[#], y[#]},
       {x[#], y[#]} + 0.2 normal[#]
       }] & /@ points
   }, PlotRange -> .7

enter image description here

share|improve this answer

Say you have this data points.

points = Table[{x[th], y[th]}, {th, 0, 2 Pi, Pi/100}];

And this is your line.

p1 = ListLinePlot[points];

And the normals will be simply lines joining these pair of points (as per your code).

norm = Table[{{x[th], y[th]}, normal[th]}, {th, 0, 2 Pi, Pi/10}];
(*I choose here 1/10th of total points or it will be too clumsy *) 

Then you can plot them if you wish

p2 = Graphics[{Table[Line[norm[[i]]], {i, Length[norm]}],
Point[Table[norm[[i]][[1]], {i, Length[norm]}]]}, Axes -> True];

And then you combine the both.

Show[{p2, p1}]

This will look something like

Grid[{{"Plot", "Normal", "Combine"}, {p1, p2, Show[{p2, p1}]}}, Frame -> All]


Please don't mind the aspect ratios. You can always fix them.

share|improve this answer
Thanks Sumit, but the indicated line segments don't look like normals to me, under the figure named combine, Is there some bug in your code? – smilingbuddha Jul 7 '13 at 18:10
Thanks @smilingbuddha for the comment. It is because your code calculate normal at a point and it is made for a particular trajectory. When I choose only few points, the trajectory is not very clear and hence the normal doesn't appear to be 'normal'. It will be prominent when you take large number of points (what I have done now) and the normality will be more soothing to eye. – Sumit Jul 7 '13 at 19:17

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.