So I was in the middle of converting my geometry application Geostruct (we used to call them programs) into javascript

get it here with the introduction .doc file here

when I decided that the “angle between two lines” routine needed a rewrite. Some surprises ensued !

Two lines, ax + by + c = 0 and px + qy + r = 0

Their slopes (gradients) are -a/b = tan(θ) and -p/q = tan(φ)

The angle between the lines is φ – θ,

so it would be nice to know something about tan(φ – θ)

Back to basics, where tan(φ – θ) = sin(φ– θ)/cos(φ– θ),

and we have the two expansions

sin(φ– θ) = sin(φ)cos(θ) – cos(φ)sin(θ) and

cos(φ– θ) = cos(φ)cos(θ) + sin(φ)sin(θ)

So we have tan(φ – θ) = (sin(φ)cos(θ) – cos(φ)sin(θ))/( cos(φ)cos(θ) + sin(φ)sin(θ))

Dividing top and bottom by cos(φ)sin(θ) and skipping some tedious algebra we get

tan(φ – θ) = (tan(φ) – tan(θ))/(1 + tan(φ)tan(θ))

This is where the books stop, which turns out to be a real shame !

Going back to the two lines and their equations, the two lines

ax + by = 0 and px + qy = 0

have the same angle between them (some things are toooo obvious)

Things are simpler if we look at these two lines through the origin when they both have positive slope.

Take b and q as positive and write the equations as ax – by = 0 and px – qy = 0

Then the point whose coordinates are (b,a) lies on the first and (q,p) lies on the second.

Also, the slopes of the two lines are now a/b , tan(θ) and p/q , tan(φ)

Let us put these into the tan(φ – θ) equation above, and once more after tedious algebra

tan(φ – θ) = (bp – aq)/(ap + bq)

which is a very nice formula for the tan of the angle between two lines.

This is ok if we are interested just in “the angle between the lines”, but if we are considering rotations, and one of the lines is the “first” one, then the tangent is inadequate. We need both the sine and the cosine of the angle to establish size AND direction (clockwise or anticlockwise).

The formula above can be seen as showing cos(φ– θ) as (ap + bq) divided by something

and sin(φ– θ) as (bp – aq) divided by the same something.

Calling the something M it is fairly clear that (ap + bq)^{2} + (bp – aq)^{ 2} = M^{2 }

and more tedious algebra and some “observation and making use of structure” gives

M^{2 }= (a^{2} + b^{2})(p^{2} + q^{2})

and we now have

sin(φ– θ) = (bp – aq)/M and cos(φ– θ) = (bq + ap)/M

and M is the product of the lengths of the two line segments, from the origin to (b,a) and from the origin to (q,p)

It was at this point that I saw M times the sine of the “angle between” as twice the well known formula for the area of a triangle. “half a b sin(C)”, or, if you prefer, the area of the parallelogram defined by the two line segments.

Suddenly I saw all this in 2D vector terms, with bq + ap being the dot product of (b,a) and (q,p) , and bp – aq as being part of the definition of the 3D vector or cross product, in fact the only non zero component (and in the z direction), since in 3D terms our two vectors lie in the xy plane.

Why is the “vector product” not considered in the 2D case ??? It is simpler, and looking at the formula for sine , above, we have a 2D interpretation of the “vector”or cross product as twice the area of the triangle formed by (b,a) and (q,p). (just as in the standard 3D definition, but treated as a scalar).

So “bang goes” the common terms, scalar product for c . d and vector product for c X d

Dot product and cross product are much better anyway, and a bit of ingenuity will lead you to the reason for the word “cross”.

This is one of the things implemented using this approach:

Anyway, the end result of all this, for rotating points on a circle, was a calculation process which did not require the actual calculation of any angle. No arctan( ) !