Sorry about the extreme lack of posts. I hope this tip makes up for it So, this morning I load FB 4.6 and it hangs. I tried all the usual suspects and still no luck. I searched online and read the amusing story of Adobe wanting to charge people $250 for a tech support call to fix what appears to be a bug. Clearly a one-trick pony company with Photoshop – they sure can’t make anything else work.
Don’t waste your time or money with DumbDobe. A bit more searching yielded this post and it worked for me without reinstall or any other hassle. I wanted to pass along some props to the original poster and give the fix some attention in case this happens to you.
And Adobe is leading the charge for HTML 5? Yikes! I knew I should have been a lawyer.
Well, this will probably be the last, or nearly last post of a busy year that involved a lot of work on gigs and little focus on this blog. Sorry, maybe next year will be better
In the previous example, I showed how to rotate a box (rectangle) around an arbitrary point, but the algorithm and code never presumed anything about the geometric nature of the object. It’s possible to extend the exact same algorithm to a collection of points and that is the subject of the current post.
Instead of maintaining variables for the four vertices of a rectangle, the code was modified to work with an arbitrary point collection. A RotatablePoint class was used to hold data points and offload some of the computations. This greatly simplifies the actual demo and provides you with ample means for experimentation.
The online example starts with a small collection of points as shown below.
These points are rotated about the fixed point, drawn as a red dot. The drawing may be cleared after each rotation increment or continually updated from the prior drawing as shown below.
Have a Merry Christmas and I’ll try to post more next year!
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.
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) ) .
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.
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
I think I’m about to set a new personal record for lowest number of posts in a given year. Is it really October already?
Well, at least I’m working and on a pretty interesting project from both a mathematical and programming perspective, so I should be thankful for that.
To this end, I’m currently looking into both Typescript and Jangaroo. Coffeescript is on the list as well, but I’m really looking to get back into Visual Studio and C++/C# development, so Typescript has some natural appeal. Perhaps sufficient time will arise to deep-dive into all three?
I guess we’ll have to wait and see. Sorry again for the waiting part. This has been a strange (but fortunately very profitable) year.
I’m into an extension of my prior gig, so time is still very limited. In addition to family issues, what little time remains is dedicated to supporting existing beta users of the Freehand Drawing Library. And, these users just scored big time. I’ve decided to keep the library private and license it only to customers, providing requested customization at an hourly rate.
Thanks for bearing with the extreme lack of posts this year
Well, this is what every contractor likes to hear – “you’ve been extended.” Although relatively short, it means that between the gig, taking care of family, and supporting users of the Freehand Drawing Library, my lack of blogging will also be extended for a while.
On a personal note, I hope to get back into tennis after being out of practice since April due to a foot injury. Looking forward to hitting this afternoon instead of just watching the US Open
Okay, well, I hope that tells you where my summer is at this point and helps explain the lack of posts. With some luck, I’ll be back to work on the Freehand Drawing Library later this month.
No, I haven’t bugged out. Just going through the typical ‘long haul through the summer.’ For some reason, it’s been this way every year since 2006. It’s a nice problem to have, however, so no complaints here. Just no posts for a while.