How to draw a rectangle or curve between two co-ordinates in libGDX - libgdx

I am new to libGDX.I just want a Rectangle or a small curve drawn between the object and the clicked position .I know libGDX has RECTANGLE class but I need to rotate it but the problem is, it gets rotated in center origin and i want to rotate it from its starting position.
I just want to draw a rectangle or a curved line to be drawn between the object and the clicked position like this >>>
Code to get user click position :
int x1 = Gdx.input.getX();
int y1 = Gdx.input.getY();
Code to get the width(distance) between the object and the clicked position :
float abwidth = x1 - position.x;
Code to compute the rotation :
float f1 = Math.abs(y1 - position.y);
float f2 = Math.abs(x1 - position.x);
abwidth = Math.abs(abwidth);
float abdegree = Math.toDegrees(Math.atan((f1)/(f2)));
abdegree = abdegree * (-1);//done this because it was giving the opposite rotation i dont know if this is wrong but it made the angle upwards
The above computed degree when put in the following code -- > shapeRenderer.rect(x,y,width,height, 0, 0, abdegree ); is not giving me the perfect angle So what would be a perfect way to rotate the straight horizontal rectangle to the click position.
Or is there any way of achieving this in some other way instead of using rectangle like using curve or something else ?

You can use this class for rendering shapes
and it has
rect(float x, float y, float width, float height, float originX, float originY, float rotation)
method for drawing rectangles
set originX,originY to 0,0 or other numbers to change rotation origin point

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 Tiled map object to box2d body location

A Tiled map object hat a position x, y in pixels and a rotation in degrees.
I am loading the coordinates and the rotation from the map and trying to assign them to a box2d Body. There are a couple of differences between the location models, for example Tiled object rotation is in degrees and box2d body angle is in radians.
How do I convert the location to the BodyDef coordinates x, y and angle so that the body will be created at the correct position?
Background:
Using the code:
float angle = -rotation * MathUtils.degreesToRadians;
bodyDef.angle = angle;
bodyDef.position.set(x, y);
Works when the rotation is 0, but the body is not positioned correctly when rotation is different than 0.
I found a couple of hints here:
http://www.tutorialsface.com/2015/12/qu ... dx-solved/
and here:
https://github.com/libgdx/libgdx/issues/2742
That seem to tackle this exact problem, however neither solution worked for me, the body objects are still positioned wrong after applying those transformations. By positioned wrong I mean that the body is positioned in the area of the map where it should be but slightly off depending on its rotation.
I feel that it should be pretty simple but I do not know how to mediate the differences between Tiled and box2d locations.
For reference these are the two solutions I tried from the links above (after transforming the values x, y, width, height from pixels to world units):
float angle = rotation * MathUtils.degreesToRadians;
bodyDef.angle = -angle;
Vector2 correctionPosition = new Vector2(
height * MathUtils.cosDeg(-rotation - 90),
height + height * MathUtils.sinDeg(-rotation - 90));
bodyDef.position.set(x, y).add(correctionPosition);
and
float angle = rotation * MathUtils.degreesToRadians;
bodyDef.angle = -angle;
// Top left corner of object
Vector2 correctedPosition = new Vector2(x, y + height);
// half of diagonal for rectangular object
float radius = (float)Math.sqrt(width * width + height * height) / 2.0f;
// Angle at diagonal of rectangular object
float theta = (float)Math.tanh(height / width) * MathUtils.degreesToRadians;
// Finding new position if rotation was with respect to top-left corner of object.
// X=x+radius*cos(theta-angle)+(h/2)cos(90+angle)
// Y=y+radius*sin(theta-angle)-(h/2)sin(90+angle)
correctedPosition = correctedPosition
.add(
radius * MathUtils.cos(theta - angle),
radius * MathUtils.sin(theta - angle))
.add(
((height / 2) * MathUtils.cos(MathUtils.PI2 + angle)),
(-(height / 2) * MathUtils.sin(MathUtils.PI2 + angle)));
bodyDef.position.set(correctedPosition);
Any hint would be highly welcomed.
Found the correct solution, lost about 1 day of my life :)
The information from above links is incorrect and/or outdated. Currently Tiled saves the object position depending on it's type. For an image is relative to bottom-left position.
Box2d doesn't really have an "origin" point, but you can consider is its center and the shapes of the fixtures attached to the body should be positioned relative to (0,0).
Step 1: Read tiled properties
float rotation = textureMapObject.getRotation();
float x = textureMapObject.getX();
float y = textureMapObject.getY();
float width = textureMapObject.getProperties()
.get("width", Float.class).floatValue();
float height = textureMapObject.getProperties()
.get("height", Float.class).floatValue();
Step 2: Scale these acording to your box2d world size, for example x = x * 1/25; etc.
Step 3: Create a body without any position or angle.
Step 4: Transform body position and angle with:
private void applyTiledLocationToBody(Body body,
float x, float y,
float width, float height,
float rotation) {
// set body position taking into consideration the center position
body.setTransform(x + width / 2, y + height / 2, 0);
// bottom left position in local coordinates
Vector2 localPosition = new Vector2(-width / 2, -height / 2);
// save world position before rotation
Vector2 positionBefore = body.getWorldPoint(localPosition).cpy();
// calculate angle in radians
float angle = -rotation * MathUtils.degreesToRadians;
// set new angle
body.setTransform(body.getPosition(), angle);
// save world position after rotation
Vector2 positionAfter = body.getWorldPoint(localPosition).cpy();
// adjust position with the difference (before - after)
// so that the bottom left position remains unchanged
Vector2 newPosition = body.getPosition()
.add(positionBefore)
.sub(positionAfter);
body.setTransform(newPosition, angle);
}
Hope it helps.

clearRect issue in animation

Im having issue with clearRect, i have an image u can move up and down and which follow the angle where the mousse is but in some frames of the animation the clearRect let a small edge of the previous image state ( 'this' reference to the image and 'ctx' is the 2d context, 'this.clear()' is called each frame before redrawing the image at the new coordinates )
this.clear = function(){
game.ctx.save();
game.ctx.translate(this.x+this.width/2, this.y+this.height/2);//i translate to the old image center
game.ctx.rotate(this.angle);//i rotate the context to the good angle
game.ctx.clearRect(this.width/-2, this.height/-2, this.width, this.height);//i clear the old image
game.ctx.restore();
};
if i replace the clearRect line by
game.ctx.clearRect(this.width/-2-1, this.height/-2-1, this.width+2, this.height+2);
it works but its not the logical way
The problem is that you are only clearing at position half the width/height, not position minus half the width/height.
Regarding anti-aliasing: when you do a rotation there will be anti-aliased pixels regardless of the original position being integer values. This is because after the pixels relative positions are run through the transformation matrix their offsets will in most cases be float values.
Try to change this line:
game.ctx.clearRect(this.width/-2, this.height/-2, this.width, this.height);
to this instead including compensation for anti-aliased pixels (I'll split the lines for clearity):
game.ctx.clearRect(this.x - this.width/2 - 1, /// remember x and y
this.y - this.height/2 - 1,
this.width + 2,
this.height + 2);

How do i get the x/y coordinates of the first and last points of the drawn arc relative to the top left corner of the canvas?

I have a square canvas with a width of 100 and a height of 100.
Within that square I draw an arc like so:
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.clearRect(0,0,100,100) // clears "myCanvas" which is 100pixels by 100 pixels
ctx.beginPath();
ctx.arc( 50, 50, 30, 0, Math.PI*2/6 , false )
ctx.stroke();
The question is: How do i get the x/y coordinates of the first and last points of the drawn line relative to the top left corner of the canvas?
The starting point is trivially (x + radius, y). The ending point is, by simple trigonometrics, (x + radius*cos(angle), y + radius*sin(angle)). Note that the starting point in this case is a special case of the more general ending point, with angle equal to zero. These values also need to be rounded to the nearest integer, for obvious reasons.
(Note that this applies only when the anticlockwise argument is false, and assuming all coordinates are measured from the top left. If anticlockwise is true, reverse the sign of the second component of the y coordinate. If coordinates are measured from another corner, apply simple arithmetics to correct for this. Also note that this is completely backwards for any real mathematician.)

How to get visual corner (eg. topLeft) of rotated displayObject in actionscript 3?

When rotating a display object (around its center) the visual corner of the element moves (the actual x and y of the "box" remains the same). For example with 45 degrees of rotation the x coordinate will have increased and the y coordinate will have decreased as the top left corner is now at the top center of the "box".
I've tried to use displayObject.getBounds(coordinateSpace).topLeft however this method is simply returning the x and y of the box and thus doesn't change after an object has been rotated.
So, how do you get the x and y of a visual corner of a rotated display object?
Update: this is what I mean with the position of a visual corner after rotation -->
alt text http://feedpostal.com/cornerExample.gif
You simply need to translate the point to its parent's coordinate space.
var box:Shape = new Shape();
box.graphics.beginFill(0xff0099);
box.graphics.drawRect(-50, -50, 100, 100); // ... the center of the rectangle being at the middle of the Shape
addChild(box);
box.x = 100; // note: should be 100 + box.width * .5 in case you want to use the topleft corner to position
box.y = 100;
box.rotation = 45;
// traces the result (Point)
trace( box.parent.globalToLocal(box.localToGlobal(box.getBounds(box).topLeft)) );