Handle Location or Registration Point change...

26 views
Skip to first unread message

Jake

unread,
Jul 21, 2010, 9:05:07 PM7/21/10
to Flex ObjectHandles
Hi all,
Is there a way to get the real x,y location of the handles. something
like:
oh.topLeftHandle.x... If I could get the real x,y coordinates (not
just local).. then I could get the center point of the Rectangle..
So here is my important question:
Is it possible to set the registration point to the center? Or is
there an easy way to find that center point?
I am thinking of all types of Trig.. but I can't seem to figure out
that center point unless I have the x.y of those handles. I am trying
to send this data over to box2d but of course that works with
registration points in the center.

Steven Rubenstein

unread,
Jul 22, 2010, 12:13:05 AM7/22/10
to object...@googlegroups.com
Jake,

I feel your pain. I had the same problem. The true solution is to master the mysterious matrix function in Flash. But I instead resorted to using trig and some creativity. I am fairly confident that my solution works. It finds the original, pre-rotated top-left x,y of an object -- and its center point as well if you need that.

In case you care, the complication in using trig is that pythagorean theorem works, but which side is "a" which is "b" depends on which quadrant of an x,y graph (with negative values) the triangle is in. And the rotation value also must account for the fact that at rotation = 0, the angle is actually 45 degrees. It took some trial and error, to say the least.

I have copied my ActionScript code below. I also have a version in ColdFusion, which is where I am primarily using it. I also have a ColdFusion function that determines the new top-left X,Y if you change the rotation value from r1 to r2. Let me know if you want that.

The following code is within an event handler function which receives input (event:Event). For the record, this code is for OH1.

If you have any questions, let me know.


var targetObject:ObjectHandles =  event.target as ObjectHandles;

var newRotation:int = targetObject.rotation;
var newX:int = targetObject.x;
var newY:int = targetObject.y;

trace("1. New Rotation = " + newRotation + ". New X = " + newX + ". New Y = " + newY);

var h2:Number = Math.pow(targetObject.height / 2, 2);
var w2:Number = Math.pow(targetObject.width / 2, 2);
var centerRadius:Number = Math.sqrt(h2 + w2); // c
var centerPointX:Number = targetObject.x;
var centerPointY:Number = targetObject.y;

if (newRotation == 0)
{
centerPointX += (targetObject.width / 2);
centerPointY += (targetObject.height / 2);
}
else if (newRotation == 90)
{
centerPointX -= (targetObject.height / 2);
centerPointY += (targetObject.width / 2);
}
else if (newRotation == 180 || newRotation == -180)
{
centerPointX -= (targetObject.width / 2);
centerPointY -= (targetObject.height / 2);
}
else if (newRotation == -90)
{
centerPointX += (targetObject.height / 2);
centerPointY -= (targetObject.width / 2);
}
else // ????
{
var angleZero:Number = Math.atan((targetObject.height / 2) / (targetObject.width / 2)) * 180 / Math.PI;
newRotation += angleZero;
trace("2. angleZero = " + Math.round(angleZero) + ". newRotation = " + newRotation);

if (newRotation > 90) // 91-179
newRotation = newRotation - 90;
else if (newRotation > 0) // 1-89
newRotation = newRotation;
else if (newRotation < -90) // -91 - -179
newRotation = 180 + newRotation;
else // -1 - -89
newRotation = -1 * newRotation;

trace("3. newRotation = " + newRotation);

var rotationRadians:Number = newRotation * (Math.PI / 180);
var a:Number = centerRadius * Math.sin(rotationRadians);
var b:Number = centerRadius * Math.cos(rotationRadians);
trace("4. a = " + a + ". b = " + b + ". centerRadius = " + centerRadius);

if ((targetObject.rotation + angleZero) > 90) // 91-179
{
trace("5. rotation > 90"); // ????
centerPointX = targetObject.x - a;
centerPointY = targetObject.y + b;
}
else if ((targetObject.rotation + angleZero) > 0) // 1-89
{
trace("5. rotation > 0") // ????;
centerPointX = targetObject.x + b;
centerPointY = targetObject.y + a;
}
else if ((targetObject.rotation + angleZero) < -90) // -91 - -179
{
trace("5. rotation < -90"); // ????
centerPointX = targetObject.x - b;
centerPointY = targetObject.y - a;
}
else // -1 - -89
{
trace("5. else -1 - -89"); // ????
centerPointX = targetObject.x + b;
centerPointY = targetObject.y - a;
}
}

trace("6. Center Point (x,y) = " + Math.round(centerPointX) + ", " + Math.round(centerPointY)); 

var topLeftPointX:Number = centerPointX - (targetObject.width / 2);
var topLeftPointY:Number = centerPointY - (targetObject.height / 2);
trace("7. Top Left Point (x,y) = " + Math.round(topLeftPointX) + ", " + Math.round(topLeftPointY));




--
You received this message because you are subscribed to the Google Groups "Flex ObjectHandles" group.
To post to this group, send email to object...@googlegroups.com.
To unsubscribe from this group, send email to objecthandle...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/objecthandles?hl=en.


Marc Hughes

unread,
Jul 22, 2010, 9:20:26 AM7/22/10
to object...@googlegroups.com
I might be missing something, but I think localToGlobal method is all you need.

If you have a display object that's 50x50 the center is 25,25 in local coordinates.  Pass that into localToGlobal and you'll get the global coords.

globalPoint = handle.localToGlobal( new Point(25,25) );

http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/display/DisplayObject.html#localToGlobal%28%29

-Marc

Steven Rubenstein

unread,
Jul 22, 2010, 10:00:03 AM7/22/10
to object...@googlegroups.com
Marc,

You are correct for square objects, but I believe finding the center point for non-square objects is more difficult.

(And in my defense, I needed to do the calculation within ColdFusion, not Flex. So I had to do it the hard way. I simply wrote the code in Flex initially for testing.)

 Steven

Jacob Schatz

unread,
Jul 22, 2010, 11:26:22 AM7/22/10
to object...@googlegroups.com
I will figure out this calculation and then post it. So far I have it from all your really great posts. Steven I think your solution may work but it may be a little too verbose. 
What I have so far:
Return the rectangle object.  Get topleft and bottomright.
Use the midpoint formula to get the midpoint. Now we have the center of the rectangle. Now only one more thing has to happen. We have to take into account the changes that happened to the topleft x&y while rotating. Will post the code once I figure it out completely.
Best,
Jacob.   
Sent from my iPhone

Jake

unread,
Jul 28, 2010, 8:36:21 PM7/28/10
to Flex ObjectHandles
Guys here is how you calculate a registration point that is on the top
left corner.. to the center.. Aka: Object handles to Box2d or
something like that..
first you want to find the center of the rectangle..
use this getCenter function (below) and pass it your rectangle...which
you can get by knowing the x y width and height of your shape..
getCenter(new Rectangle(x,y,width,height))
Then use this rotation Matrix function to find out how much x and y
have changed since you rotated it... (you don't need to do this second
part if your rectangle didn't rotate... Make sure all the rotation
info is in radians.. so you pass x y width height and radians that
have rotated to rotationMatrix..
So implementing it would probably look something like this:

var cp:Point = getCenter(new Rectangle(x,y,width,height));
if(Number(rotation) != 0)
{
cp.x = rotationMatrix(x,y,width,height,Number(rotation)).x;
cp.y = rotationMatrix(x,y,width,height,Number(rotation)).y;
}
then you will have a properly translated registration point.
Heres the functions:

private function
rotationMatrix(x:Number,y:Number,w:Number,h:Number,rads:Number):Point
{
//rotation matrix formula;
//opposite direction because of flash

var startingPointX:Number = 0 - (w / 2);
var startingPointY:Number = 0 + (h / 2);

//the big guns.. The Rotation Matrix formula for opposite direction
var x1:Number = Math.cos(rads) * startingPointX + Math.sin(rads) *
startingPointY;
var y1:Number = -Math.sin(rads) * startingPointX + Math.cos(rads) *
startingPointY;

var endX:Number = x - x1;
var endY:Number = y + y1;

return new Point(endX, endY);
}

private function getCenter(rect:Rectangle):Point
{

var topleft:Point = rect.topLeft;
var bottomright:Point = rect.bottomRight;
//midpoint formula
var px:Number = (topleft.x + bottomright.x) / 2;
var py:Number = (topleft.y + bottomright.y) / 2;
return new Point(px,py);
}

get Center uses the midpoint formula.
Let me know how this works for you.
I used the opposite Rotation Matrix formula since flash's coordinate
system is different than most.. where rotation is clockwise instead of
counter clockwise. and 0,0 is in the top left corner.

On Jul 22, 11:26 am, Jacob Schatz <playpianolikew...@gmail.com> wrote:
> I will figure out this calculation and then post it. So far I have it from
> all your really great posts. Steven I think your solution may work but it
> may be a little too verbose.
> What I have so far:
> Return the rectangle object.  Get topleft and bottomright.
> Use the midpoint formula to get the midpoint. Now we have the center of the
> rectangle. Now only one more thing has to happen. We have to take into
> account the changes that happened to the topleft x&y while rotating. Will
> post the code once I figure it out completely.
> Best,
> Jacob.
> Sent from my iPhone
>
> On Jul 22, 2010, at 9:20 AM, Marc Hughes <
>
> flexcompone...@rogue-development.com> wrote:
>
> I might be missing something, but I think localToGlobal method is all you
> need.
>
> If you have a display object that's 50x50 the center is 25,25 in local
> coordinates.  Pass that into localToGlobal and you'll get the global coords.
>
> globalPoint = handle.localToGlobal( new Point(25,25) );
>
> http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/d...
> > On Wed, Jul 21, 2010 at 6:05 PM, Jake <playpianolikew...@gmail.com> wrote:
>
> >> Hi all,
> >> Is there a way to get the real x,y location of the handles. something
> >> like:
> >> oh.topLeftHandle.x... If I could get the real x,y coordinates (not
> >> just local).. then I could get the center point of the Rectangle..
> >> So here is my important question:
> >> Is it possible to set the registration point to the center? Or is
> >> there an easy way to find that center point?
> >> I am thinking of all types of Trig.. but I can't seem to figure out
> >> that center point unless I have the x.y of those handles. I am trying
> >> to send this data over to box2d but of course that works with
> >> registration points in the center.
>
> >> --
> >> You received this message because you are subscribed to the Google Groups
> >> "Flex ObjectHandles" group.
> >> To post to this group, send email to object...@googlegroups.com.
> >> To unsubscribe from this group, send email to
> >> objecthandle...@googlegroups.com<objecthandles%2Bunsu...@googlegroups.com>
> >> .
> >> For more options, visit this group at
> >>http://groups.google.com/group/objecthandles?hl=en.
>
> >  --
> > You received this message because you are subscribed to the Google Groups
> > "Flex ObjectHandles" group.
> > To post to this group, send email to object...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > objecthandle...@googlegroups.com<objecthandles%2Bunsu...@googlegroups.com>
> > .
Reply all
Reply to author
Forward
0 new messages