How do I get the global point of a rotated object? - actionscript-3

I'm trying to get the global point (x,y) of an object. This object is a child of a rotated parent, MovieClip. Without rotation of the parent, it's easy to find the global point of the child, parent.localToGlobal. However, when I'm rotating the parent, it seems that localToGlobal returns the incorrect x,y.

localToGlobal deals with position not transformation. You are simply using the wrong tool for the job. I'm guessing you don't want to deal with matrices but you gonna have to.
mydisplayobject.transform.pixelBounds;//global space occupied by object
mydisplayobject.transform.concatenatedMatrix//the matrix representing all combined transofrmations

Related

Libgdx rotating ellipse for collision detection

I try to use 2 ellipses to detect a collision if they overlap. I have to rotate the ellipses but I can't figure out how this works. I'm working with the "com.badlogic.gdx.math.Ellipse" class but it seems to have no method for rotating. Any ideas? Thx in advance!!
Unfortunately, LibGDX doesn't have in-built rotating functions for ellipses.
Instead, I'd either be resorting to a circle in which rotation does not matter, or use polygons to check intersection.
Polygons are formed through an array of float values (vertices), where, every even element of the array is the horizontal component (x) and the odd, the vertical component (y).
Polygon polygon1 = new Polygon(vertexSet1);
Polygon polygon2 = new Polygon(vertexSet2);
Then, by using an Intersector, you can then check whether these polygons have intersected. The more vertices, the more accurate your shape will be. Just remember to have 6 or more elements in your vertex array, as the 6 floats will give 3 (x, y) points which is the minimum required for a polygon.
if (intersector.overlapConvexPolygons(polygon1, polygon2) {
//do your intersection code
}
The polygons themselves have commands to translate, scale and rotate, allowing for the rotations you mentioned above.

Object does not rotate around pivot point

I have an object which looks like this:
When I try to rotate it using [INSTANCENAME].rotation += 10;
it still rotates around the middle of the object. Am I doing something wrong?
I've done a little research, and apparently there is no direct way to change the pivot point programmatically, AFAIK. Rather odd, seeing as you can change it in the Flash Pro IDE. (For those reading, the pivot point is NOT the same as the registration point.)
[EDIT: Thinking more about it, I don't think the pivot point actually "exists", at least in the context of a programmable property. It only exists in the context of some tools in the Flash IDE.]
You will need to place your object ALONE inside another object, so that the desired pivot point of the inner object is over the center of the outer object. Then, rotate the outer object.
You can later control your object's "pivot point" by changing the position of the inner object.
Since the outer object's center moves depending on its size, and the position of the inner object determines the size of the outer object, you'd need to apply some math. The x position of the inner object would need to be equal to the distance from the desired pivot point on the inner object to the far right edge of that inner object. The same concept applies to the y position.
This can be accomplished both in the IDE directly, or through code, whichever you choose.
An example of code to change this dynamically. This function is inside the outer object. (You can get pivotX and pivotY off an event listener, if you want.) [Sorry, the code is untested.]
function newPivot(int pivotX, int pivotY):void
{
inner.x = inner.width - pivotX;
inner.y = inner.height - pivotY;
}
I hope that solves your problem!
A very simple way is to do like this.
Convert the image to a symbol(MovieClip). [you might have already done it].
Double Click on the MovieClip/Sprite to enter inside.
Move the Image so that the registration point align towards the pivot.
NB: Applicable only in case of FLASH IDE.

ActionScript 3 Simple Projectile Pathing

Good evening (at the time of writing)
The research I've done on this topic has turned up numerous fruitful code blocks regarding various situations similar to mine, but not quite identical. If one exists which I have not uncovered, I would be grateful for a link!
I have a few pertinent criteria, all on a 2d plane, and the question is related to 2d projectile pathing:
1) Object A: position ax,ay
2) Object B: position bx, by
3) Object P: (projectile) origin position bx,by
Object P leaves object B's X/Y position at a static velocity, traveling toward object A's X/Y position.
Objects A and B continue to move along their paths, irrespective of object P's trajectory. Object P continues to move from ax,ay to bx,by and beyond. I think I just need the angle and velocity, and don't need to continue to track beyond that (just increment movement steps accordingly till off-stage, where the object is disposed).
I'm working in Actionscript 3, any help would be greatly appreciated. Thanks!
In most case in 2D x-y plane, it is usually easier to handle movement and momentum in planar(separate in x-axis and y-axis) fashion than polar(angle+distance) fashion. I couldn't get the exact behaviour of projectile you want, so I assume you want a simple, dumbfire-rocket style projectile (which keeps initial direction).
:: 1. Projectile initiation ("Firing" of projectile)
var duration:int //(duration of flight(until getting to (ax,ay) described in number of frames)
var spdX:Number //(x-axis part of speed, described in pixels per frame)
var spdY:Number //(y-axis part of speed, described in pixels per frame)
spdX=(bx-ax)/duration;
spdY=(by-ay)/duration;
:: 2. Projectile movement (listen to ENTER_FRAME Event, executed once per frame)
projectile.x+=spdX;
projectile.y+=spdY;
:: if you want to change velocity of projectile, simple multiplication will handle it.
public function adjustSpeed(ratio:Number):void
{
spdX*=ratio;
spdY*=ratio;
}

localToGlobal/globalToLocal AS3 confusion

I want to move a display object from one container to another, but have it appear in the same place on screen.
I thought I'd understood this years ago, but the following does not work:
function moveToNewContainer(obj:DisplayObject, newParent:DisplayObjectContainer):void {
var pos:Point = new Point(obj.x, obj.y);
var currentParent:DisplayObjectContainer = obj.parent;
pos = currentParent.localToGlobal(pos);
currentParent.removeChild(obj);
newParent.addChild(obj);
pos = newParent.globalToLocal(pos);
obj.x = pos.x;
obj.y = pos.y;
}
This doesn't position the object in the same place as I would have expected.
Does anyone know what I am doing wrong, please?
Thanks,
James
Using localToGlobal/globalToLocal and setting the x and y properties like you showed calculates the correct position for the object in its new parent, but does not adjust for other aspects of the transformation such as scaling or rotation. In other words, the object's registration point will indeed remain in the same place, but the object may be rotated, scaled, or sheared differently.
The solution to your problem will need to take into account the transform.concatenatedMatrix properties of the old and new parents--you'll need to multiply the object's transformation matrix by one and then by the inverse of the other, or something along those lines. Leave a comment if you need help working out the math.
There is nothing wrong with your code, provided that both containers have no transformations applied. If your clips are scaled, rotated, etc.. you need to handle that in addition to the coordinate space transformations that localToGlobal and globalToLocal do.
You have to check if your containers are actually placed on stage. If your new container isn't added as a child to stage, function globalToLocal fails, just because it doesnt know how to correctly calculate that data.

AS3 - Using Matrix3D objects for reordering display

I'm working with about 20 objects that are moving around in 3D space. Adobe recommends "Using Matrix3D objects for reordering display":
Use the getRelativeMatrix3D() method of the Transform object to get the relative z-axes of the child 3D display objects.
Use the removeChild() method to remove the objects from the display list.
Sort the display objects based on their relative z-axis values.
Use the addChild() method to add the children back to the display list in reverse order.
Great. That's fine if the objects aren't moving. But what if there are animations happening and one object comes in front of another in z-space? The objects are displayed accoring to the position in the display list, not according to their z-order. How can you make objects respect z-order while animating (make object A appear in front of object B if object A's z-value becomes smaller than object B)? Obviously you can't clear the display list during an animation.
It's practically the same as adobe's docs says... and it works perfectly for moving objects.
The simplest way, so you have some code reference, and given you have all of your 3d objects in an array, would go something like this:
function zSort(objects:Array) {
objects.sortOn("z", Array.DESCENDING | Array.NUMERIC); // sort the array on the "z" property
for each(var clip:DisplayObject in objects) { //loop the array and add the childs in the corrected order...
addChild(clip);
}
}