A Flash Developer Resource Site

Thread: set number of objects around circle rotated

1. set number of objects around circle rotated

I've been going mad trying to solve what I think should be a relatively simple problem, but I think I've just been going in circles (intended) for too long to figure anything out at this point.

Basically I am generating dynamic textfields in a loop within these movieclips with centered reg points. If it's on one side of the page I have each one stacking from the bottom up at an equal degree spread at the radius plus a set distance from center. You can see what I mean in the diagram I attached.

However, I'm having a really hard time getting the rotation right, and an even harder time figuring how to get them to lay out on the left hand side the same way as if they are on the right hand side of the page.

Has anybody done anything like this? If so, I sure wouldn't mind a hint as I'm getting closer to my deadline and this part of the project is really bogging me down right now.

2. I guess one help would be repositioning the textfields in container clips to set the reg point in an easier spot if on the left hand side. Even so, I still don't seem to be getting the formulas quite right for the rotation.

3. Code:
package {

import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.text.Font;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;

public class CircleExample extends Sprite {

public static const TEXT:String       = "dynamic text";
public static const TOTAL_FIELDS:uint = 10;
public static const CENTER:Point      = new Point(200.0, 200.0);
public static const RADIUS:Number     = 100.0;
public static const ROTATION:Number   = (2*Math.PI) /
CircleExample.TOTAL_FIELDS;

[Embed(source="nasaliza.ttf", fontFamily="Nasaliza")]
private var NasalizaFont:Class;

public function CircleExample() {

var nasaliza:Font = new NasalizaFont();
var format:TextFormat = new TextFormat;
format.font = nasaliza.fontName;

var accumulator:Number = 0.0;
for(var i:int=0;i<CircleExample.TOTAL_FIELDS;++i) {
var field:TextField = new TextField();

field.embedFonts        = true;
field.defaultTextFormat = format;
field.autoSize          = TextFieldAutoSize.LEFT;
field.text              = CircleExample.TEXT;

CircleExample.place(field,
CircleExample.CENTER,
accumulator,
accumulator += CircleExample.ROTATION;

}
}

// center rotation distance
public static function place(graphic:DisplayObject,
c:Point,
r:Number,
d:Number):void {
var m:Matrix = graphic.transform.matrix;

m.translate(-graphic.width*0.5, -graphic.height*0.5);
m.rotate(r);

if(m.d < 0) {
m.rotate(Math.PI);
d *= -1;
}
m.translate(c.x + m.d*d, c.y + m.b * d);

graphic.transform.matrix = m;
}
}

}
Hope this helps.

4. Two questions for you?

1. What is the purpose of this conditional? Seems to work without it

Actionscript Code:
if(m.d < 0) {
m.rotate(Math.PI);
d *= -1;
}

2. Why do you call CircleExample.WHATEVER everywhere? You can omit the CircleExample from all the const you've set up. for instance:

Actionscript Code:
package {

import flash.display.DisplayObject;
import flash.display.Shape;
import flash.display.Sprite;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.text.Font;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;

public class CircleExample extends Sprite {
public var center:Point;
public static const TOTAL_ITEMS:uint = 60;
public static const RADIUS:Number = 100.0;
public static const ROTATION:Number = (2 * Math.PI) / TOTAL_ITEMS;
private var cont:Sprite;
private var myItem:Shape;

public function CircleExample() {
center = new Point(stage.stageWidth * .5, stage.stageHeight * .5);

var accumulator:Number = 0.0;

cont = new Sprite();

for (var i:int = 0; i < TOTAL_ITEMS; i++) {

myItem = new Shape();
myItem.graphics.beginFill(0x000000, 1);
myItem.graphics.drawRoundRect(0, 0, 20, 4, 4);
myItem.graphics.endFill();

place(myItem, center, accumulator, RADIUS);

accumulator += ROTATION;
}
}

//center rotation distance
public function place(graphic:DisplayObject, c:Point, rot:Number, rad:Number):void {
var m:Matrix = graphic.transform.matrix;
m.translate(-graphic.width * 0.5, -graphic.height * 0.5);
m.rotate(rot);
m.translate(c.x + m.a * rad, c.y + m.b * rad);

graphic.transform.matrix = m;
}
}
}

5. Originally Posted by worked
1. What is the purpose of this conditional? Seems to work without it

Actionscript Code:
if(m.d < 0) {
m.rotate(Math.PI);
d *= -1;
}
The example still compiles, if that's what you mean. The orientation of the objects is affected by the branch, though. The idea was to have the text aligned such that it appeared 'most upright'. Without the conditional, half of the items are 'more upside down than right side up'. I realize this description is about as informal as it gets, so I'll understand if you don't understand.

Also, I do not clearly remember writing this code, but given the cryptic nature and the lack of explanation, I will guess that I was under time constraits or similar.

2. Why do you call CircleExample.WHATEVER everywhere? You can omit the CircleExample from all the const you've set up.
Only to be explicit. I would also prefix member variables with "this.", etc. In Actionscript, this becomes a stylistic preference for the most part. Suffice to say, in some language there are other significant ramifications (and I try to keep my practices consistent where possible).

---

To make up for my previous lack of explanation, I'll say that the basis (if you'll pardon the pun) of the code is to rotate each object by the appropriate amount, and then to push the object along its "right vector" (which is encoded in its transformation matrix, along with its "up vector") the distance of the "radius".

The problem the branch addresses is for words that are "upside down". "Upside down", for our purposes, is determined by comparing the orientation of the word to the world's x-axis. If the word is rotated more than 90 degrees in either direction, it will need to be rotated 180 degrees. Rotating it as such will cause "right vector" to flip, and so the word will need to be translated the negative distance of the radius instead.

To "compare the orientation of the word to the world's x-axis", we realize that the x-axis may be represented by a vector (1, 0) (or { x in R | (x, 0) and x != 0 }). Also realize that the sign of the dot product of two vectors will indicate whether the two vectors are going in the same direction or not. So if we take the dot product of the right vector and the x-axis, we can determine if the word has been rotated more than 90 degrees when compared to the x-axis.

As a final step, the dot product can be simplified by realizing that the x-axis will always contain a zero for the y component, and that since we can pick an arbitrary vector to represent the x-axis, a positive unit vector as a choice can help simplify further:
Code:
x1*x2 + y1*y2
Simplifies to:
Code:
x1*1 + y1*0
x1 + 0
x1
Of course, by making this assumption, our code becomes tied to the world axis. Since it's tied to the world axis, we may as well use the rotation properties of the display object directly. I doubt it would affect performance, but it would certainly be more clear. Again, not doing this is likely a symptom of time constraints (or whatever). I probably approached the problem with a general solution, but then lost sight of that at some point and stuck in the simplified answer without considering it. If the full dot product was used instead, the function could accept and arbitrary axis to which the words could be aligned.

Also, I think m.d should be m.a (but I am not sure). I always forget how the matrices are set up. Both work due to the orthogonal/symmetricish nature of the linear part of the matrix for this example, but this won't always be true.

6. I don't think I know exactly what you want, and I don't know how to use text fields, yet, but I want to give it a go. I will use simple shapes that you can replace with your text filed. I will try this out.

Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•

 » Home » Movies » Tutorials » Submissions » Board » Links » Reviews » Feedback » Gallery » Fonts » The Lounge » Sound Loops » Sound FX » About FK » Sitemap

Click Here to Expand Forum to Full Width