Part of the Mathematica scripts that I’ve been writing require the generation of curved geometries and I’ve been spending a bit of time to work through different ways of achieving this. My initial solutions were quite straightforward and made use of polar co-ordinates to create an array of points, which were then converted to cartesian co-ordinates at the end to make their inclusion in the analysis scripts a little easier.

Another way to do it makes use of complex numbers, but I haven’t studied complex numbers for over 20 years and if I’m brutally honest I always struggled to work out what on earth they were really used for in the real world. I’ve been through a few texts but the practical applications have always been glossed over. One line of texts that I’ve found helpful for rediscovering lost maths skills, specifically for generating geometry, are mathematics books aimed at computer scientists rather than engineers (Vince, 2010).

So what’s a complex number? Essentially a complex number has a real part and an imaginary part and this was the part I used to struggle with as a maths student because I could never understand what use in the real world an imaginary thing could be. If we could make an imaginary part useful then we could harness the power of unicorns and dragons surely? This is where Vince (2010) has helped me decipher how complex numbers can be useful as the principles are used in geometry to rotate a point around another point.

\[\Large a = \underbrace b_{{\text{Real}}} + \underbrace {ci}_{{\text{Imaginary}}}\]

And to convert from a simple cartesian co-0rdinate into an equivalent complex number representation is quite straightforward too, you just use the relationship below.

\[\Large\left( {x,y} \right) = \left( {x + yi} \right)\]

The key concept to understand is that a cartesian co-ordinate can easily be converted to an equivalent complex number and to rotate this new co-ordinate by 90 degrees anti-clockwise you multiply this new complex number by i. If you want to rotate by a further 90 degrees, then multiply this again by i. One important thing to remember when going through this series of operations though is that i² can be simplified.

\[\Large{i^2} = – 1\]

**Example.**

So for example if we wanted to take the co-ordinate at point A and rotate it through 90 degrees, we simply multiply the point by i, then simplify and we’ll get the new co-ordinate for point B. Here’s the worked example for anyone that wants to follow along at home.

\[\Large A = \left( {1 + 2i} \right)\]

Rotate by 90 degrees, therefore multipy by i.

\[\Large\left({1 + 2i} \right)i = i + 2{i^2}\]

i² can be simplified to – 1 though

\[\Large{i + 2{i^2}} = i + 2\left( { – 1} \right)\]

Becoming

\[\Large\left({ – 2 + i} \right)\]

Once you’ve followed the working above, why not have a go at rotating B through 90 degrees to get to point C, then again to get point D and then again to get back to point A? Essentially multiplying the co-ordinates by i rotates the point 90 degrees in an anti-clockwise direction.

If you wanted to boil this down to a single expression to allow a programme to be coded this can be done quite easily and the expression is as set out below with the angle expressed in terms of degrees. This expression, takes an existing point (x,y) and rotates it by an angle θ to get the new co-ordinate (x’,y’)

\[\Large \left( {x’ + y’i} \right) = \left( {x + yi} \right).{\text{ }}{\Large e^{\frac{{2\pi i\theta }}{{360}}}}\]

**Mathematica sample code.**

Now we have this simplified expression, let’s see how hard it is write a little bit of code to calculate the angle for us using complex numbers. I don’t pretend for a second this code is either elegant or efficient, but for new programmers I think it should be fairly easy to follow. First we define a variable called coords to input a cartesian co-ordinate, this has to be in between curly brackets.

1 |
coords = {-19.94, 392.11} |

{-19.94, 392.11}

Next the angle that you wish to rotate between has to be defined, I’ve assigned this to a variable called angleRot for this example. This angle has been entered in degrees.

1 |
angleRot = {-49.45} |

{-49.45}

The next stage applies the equation above for imaginary numbers on the first line of code, with the second line extracting the Real component using the Re[ ] function for the X co-ordinate, and the imaginary component using the Im[ ] function for the Y co-ordinate.

1 2 |
shiftNodes = (coords[[1]] + coords[[2]]*I)*E^(2*π*I*(angleRot/360)); newNodes = Flatten[{Re[shiftNodes], Im[shiftNodes]}] |

{284.977, 270.066}

This gives the new position based on the co-ordinate being rotated by an angle around the origin (0,0).

**Rotate a point around another specified point.**

It’s just as straightforward to rotate a point around an arbitrary point rather than the origin it just requires an additional step that moves the co-ordinate back to the origin, then after the rotation has been completed the point is shifted back again by the same amount.

Enter co-ordinates as cartesian.

1 |
startPoint = {3, 2} |

{3, 2}

Confirm the angle by which you want to rotate the co-ordinate by degrees. All angles are measured positive from 3 o’clock in the anticlockwise direction as per complex numbers standard.

1 |
angleRot = {90} |

{90}

Now you need to declare the point which you intend to rotate around.

1 |
rotationPoint = {2, 1} |

{2, 1}

Before the rotate can begin you need to determine the distance between the origin and the rotate point, this will be the distance you have to translate the point being moved around before the rotation starts.

1 |
amountTranslate = {0 - rotationPoint[[1]], 0 - rotationPoint[[2]]} |

{-2, -1}

1 |
intNodes = startPoint + amountTranslate |

{1, 1}

The final step is to rotate the point around the origin and then move it back by the same amount that it was translated by before rotating.

1 2 |
newNodes = (intNodes[[1]] + intNodes[[2]]*I)*E^(2*π*I*(angleRot/360)); newNodes = Flatten[{Re[newNodes], Im[newNodes]}] - amountTranslate |

{1, 2}

**References.**

Vince, J. (2010). *Mathematics for Computer Graphics* (Third ed.). London: Springer.