### Archive

Archive for October, 2012

## Trig 101

In the previous post, I promised to discuss the math behind rotating a rectangular sprite about its upper, left-hand registration point; that is, the origin of the sprite in its local coordinate space is the upper, left-hand corner.  This is actually a segue into a more general discussion of rotation about an arbitrary point.

While some programming environments offer more direct capability than others, low-level math serves as a common denominator between them.  If you understand the math, then it’s easy and efficient to port capability from one environment to another.  There are also times where inlining direct computations offers opportunities for performance optimization in mobile apps or games.  So, let’s start with that age-old question of what will I ever use trig for?

The programming example in the prior post dealt with computing the axis-aligned bounding box of a rectangular sprite after rotation about its origin.  Refer to the diagram below. The original sprite in light blue is rotated through an angle, a, to the orientation shown in light red.  The origin (upper, left-hand corner) remains the same while the points A, B, and C are rotated to new positions A’, B’, and C’.  Once the coordinates of these new points are known, it is trivial to compute the AABB (axis-aligned bounding box) shown in red.

From the outset drawing to the lower, right, let the width and height of the sprite be represented by w and h, respectively.  The distance, r, is simply sqrt(w2 + h2) and the angle, b, may be precomputed using the atan2 function available in most any programming language.  Using the base definitions of sine and cosine, the coordinates of point A’ are ( w*cos(a), w*sin(a) ).  The coordinates of B’ are ( r*cos(a+b), r*sin(a+b) ).  If a+b = c, then the coordinates of C’ are computed as ( h*cos(c+Π/2), h*sin(c+Π/2) ) .

There is no need for an additional trig computation for C’ since we can use the well-known identity, sin(x+y) = sin(x)*cos(y) + sin(y)*cos(x).  cos(x+y) = cos(x)*cos(y) – sin(x)*sin(y).   cos(Π/2) = 1 and sin(Π/2) = 0.  Plug these into the identities and you should see that we can re-use the computation of cos(c) and sin(c).  Refer to the code (the rotation() mutator function) in the prior post to check your computations.  It should be easy to follow whether Actionscript, Javascript, C++, or Obj C is your language of choice.

Once we have the coordinates, the AABB is trivially computed and the computations can be easily ported to any programming environment or further optimized inside the application.  All with some very basic trig and your friendly, neighborhood pythagorean theorem 🙂  The operations could be optimized beyond what is illustrated in the code and that is left as an exercise.

Notice that we computed the rotated points in the sprite’s local coordinate space.  The AABB is often computed in parent space, so it’s necessary to translate to the origin of that space.  This is illustrated in the boundingBox() accessor function.

There is, of course, nothing special about rotation about the upper, left-hand corner.  The next example will cover rotation about the centroid of the sprite, which is a special case of rotation about an arbitrary point in the sprite’s coordinate space.  No matter what application you are working on or language you are working with, understanding what is happening ‘under the hood’ can go a long way.  I hope you found something useful in this post.

Categories: Math Tags: , , ,

## Dragging Bounds After Rotation

Ah, finally!  Some code to give away!  I was recently asked to develop a prototype for a friend.  I don’t mind helping someone out, but my general policy is that if I do something free for one person, then I do it for everyone.  All such developments are performed with the understanding that I reserve the right to post results to my blog.

This particular prototype dealt with simple dragging inside bounds with the twist that the rectangular item (most often an image) could be rotated about its upper, left-hand registration point yet still dragged only within the prescribed bounds.  This was accomplished with a DraggableItem class that extends MovieClip.  The visual symbol is associated with an instance of this class.  Rectangular bounds are assigned and the DraggableItem class dispatches events on start drag, end drag, and collision with a boundary.

Bounds are in parent space and the DraggableItem rotation method recomputes the axis-aligned bounding box after rotation.  The demo draws the AABB during rotation. The computations are a simple application of trig and the entire demo could be ported to a number of environments.  I may convert this to html/js and deconstruct the math in a subsequent series of posts.  In the mean time, realize that like most demos, this one was created hastily and only lightly tested.  Documentation is sparse, so you are on your own for the deconstruction.  There may be an issue or two that requires polishing (for example, you can rotate the visual symbol beyond bounds) and I invite people to make this demo better.  That’s what open source is all about 🙂

View demo

View source

Categories: Uncategorized