Math teachers hear the most often-uttered student phrase in history a lot more than I do, but my ears have twitched to the infamous, “I’ll never use that” or its many variants over the years. Funny how people know right now what will and will not be needed or used for the rest of their lives 🙂
Now, taken in strict isolation, a single trig or algebra formula might appear to have limited or no use in the myriad of life situations in someone’s future. It is, however, quite interesting how often problems can be solved by strategic use of a single formula from multiple areas of study. The problem discussed in this post is one such example.
In the prior post, I illustrated how some basic trig concepts could be used to solve a rotation and bounding-box problem without any presumptions or special considerations of the programming environment. This example is similar in that it illustrates how to rotate a box around an arbitrary point in its interior. The box is represented by a sequence of four coordinate pairs. It is not a Flash symbol or anything other than a sequence of coordinates. The drawing environment is simple; it can move the pen, draw lines, and draw filled circles. The programming environment contains the typical set of math functions.
Our math background includes a semester of trig, analytic geometry, and algebra. We know the very basics of vectors, but have not been introduced to matrices or matrix/coordinate transforms. As it happens, all we need to know to solve the stated problem is
1 – Polar coordinates, i.e. x = r cos(a) , y = r sin(a)
2 – Parametric equation of a straight line, i.e. P = (1-t)P0 + tP1
3 – How to add and subtract vectors
4 – How to compute the distance between two points
Refer to the diagram below.
The four points of the box are A (x1,y1), B (x2,y2), C (x3,y3), and D (x4,y4). The rotation point is R (rx,ry). The example code was written in Flex and the coordinate system in the Flash player is y-down. We are not given the coordinates of R. In fact, the box may be at an angle to the horizontal as shown in the lower, right part of the diagram. The only thing we know about R is that the component parallel to each side of the box is a fraction of that side’s length. This is where vector math can be useful.
The coordinates of R can be computed by adding the vectors V1 and V2. The percentage inputs can be converted into numbers t1 and t2 in [0,1]. The exact coordinates of the terminal points of these vectors are obtained from the parametric equation of a line. Let the non-bolded notation V1 and V2 refer to vectors from the origin representing these terminal points. Then, V1 = (1-t1)A + t1B and V2 = (1-t2)A + t2D. Since the initial point of both V1 and V2 is A, the vector constituents (Δx and Δy) are immediately available. Add the vectors and add the result to A to obtain the coordinates for R. So, we can adjust sliders that change the percentage along each side and quickly compute R regardless of any prior rotation since we should always recompute the correct coordinates for A, B, C, and D.
When R is set, imagine lines drawn from R to each of the vectors A, B, C, and D. Let the distances be r1, r2, r3, and r4, respectively. Also compute the angle each line segment makes with the horizontal using the atan2() function. Since this returns a value in [-Π, Π], a small adjustment is made to always record the angles in [0, 2Π]. This makes studying the angle computations a bit easier if you want to trace out the results as part of deconstructing the code.
Also record the initial rotation angle when R is assigned. Subsequent changes to this value rotate the box around R by some delta. If the initial angle of the box is θ, and the delta is δ, then the four points are rotated around R by an angle θ+δ. Compute the coordinates of each new vector, A, B, C, and D by using the formula for polar coordinates and add the center, R.
These concepts are illustrated in an online demo.
The percentage along each side used to compute R is adjusted by sliders as well as the rotation angle. The red dot visually identifies the rotation point, R. You may optionally display the circle traced by each of the four corner points as the box is rotated. There is a _clear (Boolean) variable in the code that you may adjust to either clear the drawing each rotation update or choose to draw over each update of the box. If the value is false, you can produce some spirograph-style drawings.
The UI was created in Flex, but the actual code is very straightforward and does not rely on anything unique to Actionscript. It could be ported to many other environment quite easily. There is also some internal documentation on how to use trig identities to reduce the number of trig computations at each rotation update.
Even more importantly, there is nothing in the code or the algorithm that relies on a box being rotated other than computing R. The actual rotation is applied to a sequence of points using the simplest of concepts from a few math disciplines. I hope this provides some sense of appreciation of problems that can be solved using only the most fundamental techniques from a few branches of applied math.