At 10:54 AM 7/7/01 -0400, Fran�ois Robitaille wrote:

>Does anyone know an algorithm that can be used to rotate a point around
>another one (I'm working in MapBasic but a simple equation may be OK).  I
>know the coordinates of both points and I wish to specify the angle in
>degrees.

A good way to do this kind of thing is with complex numbers, which after 
all are just points.  So let w be the complex number representing the first 
point (the origin of the rotation), z be the complex number representing 
the second point (to be rotated), and t be the angle.  Then multiplication 
by exp(i*t) = cos(t) + i*sin(t) will rotate any complex number by the angle 
t about the origin (positive goes from the x towards the y axis; that is, 
counterclockwise).  To rotate about w we must first translate all points so 
that w goes to the origin (which is achieved by subtracting w) and, 
afterwards, translate all points back again (which is therefore achieved by 
adding w).  Consequently the rotation formula is

         z --> (z-w) * exp(i*t) + w

Using the definition of complex multiplication you can code explicit 
formulas for the coordinates.  Write w = (u,v) and z = (x,y) and for 
simplicity write exp(i*t) = (c,s) (the cosine and sine of t).  Then the 
coordinates of z-w are (x-u, y-v), so the formula works out to be

         z = (x,y) --> ( (x-u)*c - (y-v)*s + u,  (x-u)*s + (y-v)*c + v )

*-*-*-*-*-*-*-*-*
A more elegant approach is to define a complex number class.  Complex 
numbers are just points, but you implement operators +, -, * (at a 
minimum), a method "exp", and a constant "i".  Operators + and - are vector 
addition and subtraction:

         (a,b) + (c,d) = (a+c, b+d)
         (a,b) - (c,d) = (a-c, b-d)

Operator * is implemented like this:

         (a,b) * (c,d) = (a*c - b*d, a*d + b*c)

The "exp" method is implemented as

         exp(a, b) = (exp(a) * cos(b), exp(a) * sin(b))

The constant "i" is simply the point (0, 1).

That is all that is needed to implement the rotation formula (z-w) * 
exp(i*t) + w.

For completeness, you could implement other fundamental methods.  Those of 
most importance to GIS are:

         conjugate(a,b) = (a, -b)
         Re(a,b) = a
         Im(a,b) = b
         norm(a,b) = sqrt(Re( (a,b)*conjugate(a,b) ))
         complex(a) = (a,0)
         reciprocal(a,b) = conjugate(a,b) * complex(1/norm(a,b)) {undefined 
if a=0 and b=0}
         (a,b) / (c,d) = (a,b) * reciprocal(c,d)
         ln(a,b) = (ln(norm(a,b)), atan2(b,a)) {undefined if a=0 and b=0}

Although I am using object-oriented terminology, there is nothing to 
prevent implementing the same functionality in any language that supports 
procedures that return values.  Having a system that supports operators 
+,-,*,/, the constant i, and methods conjugate, norm, reciprocal, Re, Im, 
complex, exp, and ln, will let you make short work of almost all Euclidean 
calculations and transformations that arise in GIS analysis.  It will help 
you avoid the painful--and usually unnecessary--machinations with 
trigonometry that are often seen in GIS scripts.
*-*-*-*-*-*-*-*-*
--Bill



_______________________________________________________________________
List hosting provided by Directions Magazine | www.directionsmag.com |
To unsubscribe, send e-mail to [EMAIL PROTECTED] and
put "unsubscribe MapInfo-L" in the message body.

Reply via email to