Box2D body dynamic turn around pivot point dynamically? - libgdx

In libGDX Box2D i have a DynamicBody "body" and StaticBody "anchor" and its joint from "pivot joint point" and body can turning around "pivot point" and working perfect (position 2).
Body body = Box2DUtil.addRectangle(BodyDef.BodyType.DynamicBody);
Body anchor = Box2DUtil.addRectangle(BodyDef.BodyType.StaticBody);
RevoluteJointDef revoluteJointDef = new RevoluteJointDef();
revoluteJointDef.initialize(anchor, body, anchor.getWorldCenter());
world.createJoint(revoluteJointDef);
But i want rotate the "body" to spesific angle, when simulation is running and gravity=10 etc. the body is turning to bottom its OK. When i click a button i want turn body to "myNewAngle" position As it is shown in the picture (position 1)
float myNewAngle = 0;
body.setType(BodyDef.BodyType.StaticBody);//for not effected from gravity
body.setTransform(body.getPosition(), lastAngle * MathUtils.degreesToRadians);
My problem is my "body" is turning around its origin (position 3) i want turn it aroud "pivot point" i set "body.setTransform(anchor.getPosition()" but its not worked. I can't do it with "motor" too.
How can i turn "body" around "pivot point" dynamical?

You need to rotate it's position in relation to the pivot point. Lets say we have the points fixed, body, and these has some world space coordinate .worldCoordinate. You rotate body around fixed v degrees by (pseudo-code)
pos = body.worldCoordinate() - fixed.worldCoordinate();
rotated_pos = rotateVector(pos, v);
body.setWorldCoordinate(rotated_pos);

Related

How to rotate triangle such that its base is flat straight?

considering my English is not very good. I will try to use picture
Hopefully you can get what I mean. Basically what I want is I want to rotate the triangle such that the base of the triangle is flat straight ( horizontally straight). Keep in mind, that the triangle is a shape. and I know the coordinate of each point, and each midpoint of each edges. How would I do that?
(1)
"Basically what I want is to rotate the triangle such that the
base of the triangle is flat straight (horizontally straight)."
You can simply set as point_C.y = point_B.y (this will put point C on same vertical height as point B so that now, a horizontal line between those two points will be a straight line.
(2)
"The point the triangle is formed by mouse click. Each mouse click, I
make point at (mouseX, mouseY). So, the triangle could be totally random."
I would make a var to keep count of clicks...
//# count clicks to know when straight line is needed
public var count_Clicks :uint = 0;
//# straight line via "IF" statement
private function draw_Triangle_Point (evt :MouseEvent) : void
{
count_Click += 1; //add plus 1
if (count_Clicks == 3)
{
point_C.x = stage.mouseX;
point_C.y = point_B.y; //straight (horiz) line
count_Clicks = 0; //reset
}
else
{
//draw your other two points
}
}
Hope it helps.
This seems to be an equilateral triangle so could you not just rotate the triangle 120 degrees?
If not you could use Math.atan. So plainly put you can get the x and y coordinates of a and c. Use the difference between the x's and y's to give you two vectors. Then x = adjacent, y = opposite and so Math.atan(Opp, Adj) = angle. Then select your object and rotate it an extra value of angle.
https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Math.html#atan()
Think thats what you're after
Edit
So this image is what I think you are after. I randomly drew a triangle. Now you want B.y = C.y. So if you get the angle of r you should be able to use that to rotate the triangle the correct amount so that B.y = C.y.
You will have to consider what if B.y > C.y and adapt this to make it work 100%, but in this example this should work.

Libgdx / Physics Editor Rotation of body

and a nice evening.
I've the following problem:
A Box2d dynamic body with one fixture all vertices placed with positiv x / y from the origin of the body.
http://i.stack.imgur.com/MXQRr.png
But the rotation is on body origin 0/0 not on mass center..
So I tried these approaches:
1:
Set origin of Body in the Middle of the body(vertices positive and negativ)
Problem: rotation works, Sprite positioning is nearly impossible
2:
Set mass data center =
originOfBody.x + width / 2, originOfBody.y + height / 2
Problem: It's like I'm doing nothing, still rotation around origin of body at 0, 0
In the following Code snippet you can see my instantiation.
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set(new Vector2(200, 2));
body = world.createBody(bodyDef);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.density = 0.6f;
fixtureDef.friction = 0.4f;
fixtureDef.restitution = 0.2f;
bodyLoader.attachFixture(body, "Rocket1n2", fixtureDef, WIDTH);
originOfBody = bodyLoader.getOrigin("Rocket1n2", WIDTH);
MassData data = body.getMassData();
data.center.set(Box2DUtils.getWidth(body) / 2, 0);
data.I = body.getMassData().I; //without this line programm fails with assertion
body.setMassData(data);
Vector2 cpy = data.center.cpy();
I rotate the player with following code:
body.setAngularVelocity(addition); //addition is predefined(atm 1 / -1)
I currently use Body Physics Editor from aurelia(?) with some hacks it worked, I dont have any Problems with other objects, because I dont rotate them. Placement works like a charm..
I wish I do a significant error.. Normally box2d must calculate the rotationcenter (Mass Center) automatically?
I cant help myself this time.. :(
I'd recommend getting your first approach to work.
Set origin of Body in the Middle of the body(vertices positive and
negativ) Problem: rotation works, Sprite positioning is nearly
impossible
The rotation works fine, but the sprite positioning is difficult. I had this same problem when I was making a physics game last year. What helped me was seeing exactly how the positioning worked.
Box2D bodies are center-focused. That means that calling the position of the body will give you the object's middle. Sprites are corner focused, meaning a sprite's position is it's bottom-left corner. Thus, you can't just set each of them as the same thing. I recommend shifting the sprite from the body's position down and to the left by half the body's height and width, respectively.

Increase width without moving image

I'm developing a drawing app, and I ran into a problem, and a possible solution would be to be able to resize horizontally (increase or decrease the width) of an image without altering it's pivot, but ending with a "directional resize", it means, that if I start dragging the right resize anchor, the image starts increasing it's width to the right, instead of always taking into consideration the pivot.
So, what I'm doing now is to increase the width and at the same time I move the image width/2, it works, however when I have to rotate the image.. everything starts to get broken, and even if I set the pivot in the middle of the sprite, since the image (that is contained inside the sprite) x is altered, it doesn't matter.
I've read some about matrices, but I'm not sure if this is possible.
Thanks.
There a few ways you can accomplish this. The first is to use a transform matrix.
Here is a function I use to rotate an object around a point in that fashion:
*You'll need to import fl.motion.MatrixTransformer, if not using flashPro you can get it here: https://code.google.com/p/artitem-as3/source/browse/trunk/ArtItem/src/fl/motion/MatrixTransformer.as?r=3
/**
* Rotates a displayObject around the passed local point.
* #param displayObj
* #param relativeDegrees - the relative amount of degrees to rotate the object
* #param point - a local point to rotate the object around, if null, center of bounding box will be used.
*/
public static function rotateAroundPoint(displayObj:DisplayObject, relativeDegrees:Number, point:Point = null):void {
var m:Matrix = displayObj.transform.matrix.clone();
if (!point) {
//default is center of bounding box
var r:Rectangle = displayObj.getBounds(displayObj);
point = new Point(r.x + (r.width * .5), r.y + (r.height * .5));
}
MatrixTransformer.rotateAroundInternalPoint(m, point.x, point.y, relativeDegrees);
displayObj.transform.matrix = m;
}
Another more lazy way to do this, is to use a dummy parent object and just rotate that:
var dummy:Sprite = new Sprite();
dummy.addChild(yourObjectToRotate);
//this effectively makes the anchor point of dummy in the center, so when you rotate it it rotate from the center.
yourObjectToRotate.x = -(yourObjectToRotate.width * .5);
yourObjectToRotate.y = -(yourObjectToRotate.height * .5);
dummy.rotation = 90;

HTML5 Canvas (SIMPLE PAINT APPLICATION)

I'm working on a paint application and I'm trying to centre the canvas onto the middle of the screen . Any attempts I made the detection was off(still at the top left of the screen) but it was visually appearing in the centre of the screen.
Basically it wont draw onto the canvas when I moved it to the centre of the screen.
Any help would be much appreciated , Thanks....
I HAVE MY CODE BELOW ...
It's not clear from your question how you're centring it, but you need to account for any offset of elements which contain your canvas when you attempt to map the mouse position to a position on the canvas. You can do this by including the offsetLeft and offsetTop values (see docs) of the containing element when you do your calculations.
The following will work if you're offsetting the position of the div which wraps the canvas (which I've given an id to make it easier to reference):
function move(e) {
// Get the div containing the canvas. Would be more efficient to set this once on document load
var container = document.getElementById('container');
if((e.button == 0) && (mouseIsDown)) {
g.beginPath();
document.onselectstart = function(){ return false; }
//g.fillStyle = "red";
// Account for the offset of the parent when drawing to the canvas
g.arc((e.x - container.offsetLeft) - brush, (e.y - container.offsetTop) - brush, brush, 0, Math.PI * 2);
g.fill();
g.closePath();
}
}
And a simplistic demo using your fiddle here.

Resize as a function of distance between mc's

I hope this hasn't been asked too much before. When I search I only get questions pertaining to rescaling to window size.
Now my question. I got one space ship firing a beam against another ship. I want the beam to show for some time and I want it to "bridge" the two ships. In other words, I want the beam to extend its width between the two ships.
I try to do this with a dot movie clip that is 1 pixel wide and high (and aligned left edge). I try to resize it with the following code: (target is the ship to be fire at and owner is the ship firing)
dist.vx = target.x - owner.x;
dist.vy = target.y - owner.y;
dist.dist = Math.sqrt(dist.vx*dist.vx + dist.vy*dist.vy);
width = dist.dist;
x = owner.x;
y = owner.y;
rotation = Math.atan2(target.y-y, target.x-x)*180/Math.PI;
This doesn't work as intended because 1) dot also gets alot bigger in the other dimension - how can I "turn off" this behavior? and 2) sometimes it seems to get way to wide - but only in certain angles...
Any suggestions on either solving the heigh/width scaling or on another way to achieve the same effect?
(I'm new to coding and flash.) Thanks!
By resizing a dot, you will have a rectangle...
You can dynamically create a sprite covering both ships and moveTo the hit point of one ship then lineTo the other ship... You do not need distance calculation at all. What you have to do is being careful on the placement of the sprite. So that you can calculate relative hitting points by simple math.
Suppose you have mc space contining mc ship1 and mc ship2, and hit point coords on ships are named hx, hy and you will use sprite s, calculation will be as follows.
// calculate hit points relative to mc space
var s1HX:int = ship1.x + ship1.hx,
s1HY:int = ship1.y + ship1.hy,
s2HX:int = ship2.x + ship2.hx,
s2HY:int = ship2.y + ship2.hy,
// sprite relative moveTo lineTo coords will be these.
mX: int, mY: int,
lX: int, lY: int;
// top left of sprite will be minimum of the hit coords.
s.x = (s1HX <= s2HX)? s1HX : s2HX;
s.y = (s1HY <= s2HY)? s1HY : s2HY;
// now we can get sprite relative moveTo lineTo coordinates:
mX = s1HX - s.x;
mY = s1HY - s.y;
lX = s2HX - s.x;
lY = s2HY - s.y;
The rest is implementation with using these with fancy line styles etc...
To create a new sprite:
var s:Sprite = new Sprite();
Adding / removing it to/from mc space:
space.addChild(s);
space.removeChild(s);
For graphics use the graphics object of sprite.
s.graphics
For setting line styles you can use:
s.graphics.lineStyle(...) ,
s.graphics.lineBitmapStyle(...),
s.graphics.lineGradientStyle(...)
Functions, please read the manual for usage.
After setting the line style to draw the line use:
s.graphics.moveTo(mX,mY);
s.graphics.lineTo(lX,lY);
For pulsating effects you have to do a little more complicated things such as using tween class which you can read about here: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/fl/transitions/Tween.html
Note that:
Sprites are no complicated magic, they are like mc's but they do not have timelines etc.
Sprites try to scale when width or height change programmatically. So do not touch them, moveTo lineTo automatically sets the size of a sprite...