In general terms (i.e. for an arbitrary curve, not just spirals), assuming the curve is given by x(t) and y(t), where t is some non-dimensional parameter which starts at 0 and increases from there (in Thanatomic’s post, he used \theta for the spiral, which is also the angle in polar coordinates), the curve length s(t) can be computed like this:
{ds \over dt} = \sqrt{{ds \over dt}^2 + {ds \over dt}^2}
\Rightarrow s(t) = \int^t_0 \sqrt{{ds \over dt}^2 + {ds \over dt}^2} dt
In words: As t changes by some small amount, x changes by {dx \over dt} and y changes by {dy \over dt}, and the length of that very small piece of curve is \sqrt{{ds \over dt}^2 + {ds \over dt}^2}. Integrating (adding) that up from that start of the curve gives you length of the curve for any given t. Depending on what kind of equation you’re using, there might be an easy analytical solution, or you might have to do it numerically.
If you are doing it numerically, simply counting pixels will be inaccurate because two consecutive pixels on a curve are either directly next to each other (distance 1) or diagonally offset (distance \sqrt 2), independent on what slope your curve has. So if you want to know the curve length at some point t_p, it’s a lot more accurate to compute sample points along the curve for a large-enough(*) number n:
t_i = t_p\frac{i}{n} with i = 0, 1, 2 ... n
x_i = x(t_i) , y_i = y(t_i)
Then compute the distance between neighbouring sample points on the curve:
\Delta s_i = \sqrt{(x_i - x_{i-1})^2 + (y_i - y_{i-1})^2}
And from this, you can compute the curve length for your point by adding up all the \Delta s values:
s(t_p) = \sum_{i=0}^n {\Delta s_i}
The smart way to implement this is to choose t_p to be at the end of the curve (however far the curve matters to you), then choose n to be large enough(*), sample all the x and y coordinates, compute all the \Delta s_i, and then compute the cumulative sums of \Delta s_i, i.e. just the first value, the sum of first and second, the sum of the first three … and voilá, you have the curve length at every sample point.
To compute normals: Since you already have all the point coordinates, and assuming that curvature does not change much between the sampled intervals, you can compute the direction of the tangent vector using central differences:
x'_{i} = 1/2 (x_{i+1} - x_{i-1})
y'_{i} = 1/2 (y_{i+1} - y_{i-1})
This tells us how x and y coordinate are changing and so if we plotted a line starting from (x_i + 100 x'_i , y_i + 100 y'_i) and ending at (x_i - 100 x'_i , y_i - 100 y'_i), that would be a tangent to our curve. To get a normal line, we need to turn it by 90 degrees, which is easy:
x_{\perp i} = -y'_{i}
y_{\perp i} = x'_{i}
So a line from (x_i, y_i), to (x_i + x_{\perp i} , y_i + y_{\perp i}) would be perpendicular to the curve at point i.
To draw a normal with a particular length l, you compute the length of your normal vector:
\left| \left( x_{\perp i} \atop y_{\perp i} \right) \right|= \sqrt{x_{\perp i}^2 + y_{\perp i}^2 }
and scale the normal vector accordingly (divide by its own length, multiply with the length you want):
\left( x_{\perp i} \atop y_{\perp i} \right) \frac{l} {\sqrt{x_{\perp i}^2 + y_{\perp i}^2 } }
So, you can draw the curve at any point i with parameter t_i at coordinates (x_i, y_i), it has the curve length s_i, and you can draw tangent and normal lines at whatever length you like.
Done!
If you are using spirals or circles, then this can all be done on paper (as Thanatomanic has shown), although using cos() and sin() is not very fast for a computer. With some other curve types (splines, for example), all the derivatives above are really easy to do by hand, too, and work out to simple simple functions (they look something like ax^3 + bx^2 + cx + d). In the general case, it can get messy, though…
(*) large enough: depends on how “curved” your curve is. Generally, if the distance between two samples always is less than a pixel, you’re always safe, but if the curve is not bending a lot, you can get away with much fewer sample points. If your “curve” is actually a straight line, then n=1 is absolutely accurate