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.