Trouble using atan2 to get the angle of a collision in box2d - java

So I'm using box2d to handle physics and collisions in libGDX. I'm trying to figure out the angle of the collision so that I can apply certain effects at a given angle.
Doing some research, I found that atan2 should be the math function I need to get the correct angle, but it's returning curious results. For a contact that should be in the 2nd quadrant, I'm getting angles of less than 90. For contacts that are in the 3rd and 4th quadrants, I'm getting positive numbers for the contact angle. Does anyone have any insight as to what I could be doing wrong here?
float other_x = contact.getWorldManifold().getPoints()[0].x * GameScreen.BOX_TO_WORLD;
float other_y = contact.getWorldManifold().getPoints()[0].y * GameScreen.BOX_TO_WORLD;
float playerXpos = this.getX();
float playerYpos = this.getY();
float damageAngle = (float)Math.atan2((other_y - playerYpos), (other_x - playerXpos));
damageAngle = (float) (damageAngle * (180d/Math.PI));
And yes, that index of the world manifold does have coordinate information in it. I just can't seem to figure out why atan2 is returning those values.
edit So I'm thinking that the problem isn't with atan2, but rather with the contact information that's being returned by the WorldManifold. So I guess my question is, what could be the problem, such that contact information would be off like this?

Related

How to rotate object to always face mouse?

I'm trying to make a game and I need the player(rectangle) to always be looking at the mouse, I have found some pages on this but I can't seem to understand the math.
Main:
g2d.rotate(calculateRotation, x,y);
g2d.fill(player);
g2d.rotate(-calculateRotation, x,y);
Mouse Listener:
int mx = e.getX();
int mY = e.getY();
float rotation = Math.atan((mouseX-playerX)/(mouseY-playerY)); //<--- I don't know
would it be something like this?
You should use linear algebra- instead of using sines and cosines, you use vectors.
If you have P1=(x1,y1) (where the player is) and P2=(x2,y2) (where the mouse pointer is), then you have the vector V=(x2-x1,y2-y1)=(v1,v2), which has length v=|V|=sqrt(v1^2+v2^2). Then you have the versor (which is a vector of length=1) M=(v1/v,v2/v)=(m1,m2).
Then instead of computing an angle, you can rotate points by mapping (x,y)->(x* m1-y* m2, x* m2+y*m1).
See also https://en.wikipedia.org/wiki/Rotation_matrix#In_two_dimensions
(and remember to take care in the case V=0)
Note: using atan is OK, but you will need to check the signs of x and y.. If they are both negative you'll find the wrong angle; and if one is positive and the other is negative, you still don't know if your arrow points NW or SE.

Delaunay Triangulation Incorrect Angles and Edges

The answer to Direct way of computing clockwise angle between 2 vectors was helpful in getting the clockwise angle between two vectors, but what I need to know is how to get the angle from two vectors going in the clockwise direction from a specific vector.
Here's a visual explanation of what I am trying to say. When going in the clockwise direction from the red vector, the clockwise angle is this: (Excuse the bad drawing)
But when going in the clockwise direction from the black vector, the clockwise angle is this:
EDIT: I'll rephrase my question. This is what I am trying to achieve. I have been following this old but useful link on generating triangle meshes: http://www.geom.uiuc.edu/~samuelp/del_project.html#algorithms
With the above images, I always want the angle going in a clockwise direction from a specific vector. I have been using the code from the linked SO answer to get the angle, but its incorrect in my situation
float dotProd = vx*ux + vy*uy;
float det = vx*uy - vy*ux;
float angle = MathUtils.atan2(det, dotProd);//in radians
if(angle < 0) angle += MathUtils.PI;
The angle calculation incorrectly allows unnecessary edges to be connected.
How can I fix this?
I'm sure there is a shorter way to do it, but if you know where you 0,0 is
first do a check in which quarter your vector is and then perform the calculation accordingly.
it will solve your solution but mathematically I think you can get there faster.
I did these experiments:
int[] v1={5, 2}, v2={3, 4}, v3={5, 0};
double d1=v1[0]*v2[0]+v1[1]*v2[1], d2=v1[0]*v2[1]-v1[1]*v2[0];
System.out.println(Math.toDegrees(Math.atan2(d2, d1)));
d2=v2[0]*v1[1]-v2[1]*v1[0];
System.out.println(Math.toDegrees(Math.atan2(d2, d1)));
d1=v3[0]*v1[0]+v3[1]*v1[1]; d2=v3[0]*v1[1]-v3[1]*v1[0];
System.out.println(Math.toDegrees(Math.atan2(d2, d1)));
d1=v1[0]*v3[0]+v1[1]*v3[1]; d2=v1[0]*v3[1]-v1[1]*v3[0];
System.out.println(Math.toDegrees(Math.atan2(d2, d1)));
d1=v2[0]*v3[0]+v2[1]*v3[1]; d2=v3[0]*v2[1]-v3[1]*v2[0];
System.out.println(Math.toDegrees(Math.atan2(d2, d1)));
It seems the angle computed is the immediate angle: if it's positive the direction is counter clockwise (from v3 to v2 for example), if it is negative then it is clockwise.
I used standard java atan2 I dont know what you are using.
Therefore to get the clock wise always you have to check the result: if it is positive then subtract 360 degrees.
You have to do your own experiments to confirm this negative/positive.

Why is my object moving in the wrong direction?

When two of my objects collide, I want one of them to push the other.
while (checkCollision(this, cl)){
//cl is referring to the other entity, non-cl things my entity
double an = Assist.angle(new Vector3f(cl.z, 0, cl.x),
new Vector3f(z, 0, x));
double moveZ = Math.cos(Math.toRadians(an));
double moveX = Math.sin(Math.toRadians(an));
cl.z += moveZ;
cl.x += moveX;
}
The checkCollision() method works perfectly fine, detecting if my two objects (in this case 3D ships) have collided.
I am then getting the angle between the other object and my current one, and then using that angle, I am pushing away the other object. However - It isn't working.
The other object always seems to be pushed torwards the +x direction, and the Z doesn't seem to have any strict pattern, but isn't working correctly either.
Here is my method to calculate the angle (Assist.angle()):
public static double angle(Vector3f vec1, Vector3f vec2){
double so = Math.toDegrees(Math.atan2(((vec1.z) - vec2.z), ((vec1.x) - vec2.x)));
return Math.abs(so);
}
There must obviously be something blatantly wrong here - But I'm not seeing it, and I've been working for hours to try and get this code to work.
Math.atan2() takes vector cords not angles, radian or otherwise. What it returns is in radians.
For historical reasons to stupid to go into Math.atan2() expects y before x.
http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#atan2(double,%20double)
Also I don't think that Math.abs(so) at the end is helping anything.
Take a look at this:
From your comments it sounds like you think you need Ab. You don't. If you just want to bounce off (which is a grand simplification) you need Ta and it's compliment.

Parametric trajectory equation?

I'm creating a very very simple game for fun. Realizing I needed the trajectory of an object given an angle and a velocity, it seemed logical to use this parametric equation:
x = (v*cos(ø))t and y = (v*sin(ø)t - 16t^2
I know that this equation works for a trajectory, but it isn't working with most ø values I use.
Do java angles work any differently from normal angle calculation?
My goal is for the object to start from bottom left of the window and follow an arc that is determined by the speed and angle given. However it tends to go strange directions.
The value of ø should be horizontal at 0 degrees and vertical at 90, and in the equation it refers to the angle at which the arc begins.
This is my first ever question post on this site, so if I'm missing anything in that regard please let me know.
Here is the calculating part of my code
not shown is the void time() that counts for each 5ms
also I should mention that the parX and parY are used to refer to the x and y coordinates in an unrounded form, as graphics coordinates require integer values.
Any help is much appreciated, and thank you in advance!
public void parametric()
{
parX = (float) ((speed*cos(-ø))*time);
gravity = (time*time)*(16);
parY = (float) ((float) ((speed*sin(-ø))*time)+gravity)+500;
xCoord = round(parX);
yCoord = round(parY);
}
Do java angles work any differently from normal angle calculation?
You only need to read the docs
public static double cos(double a)
Parameters:
a - an angle, in radians.
I guess you are using degrees instead of radians?

how to discover an angle between two objects?

what I want to do is the following: I have an object (blue point) and I want to point it to other object no matter where it is located around it (green point). So I need to know the angle between these two objects to do what I want right?
http://s13.postimage.org/6jeuphcdj/android_angle.jpg
The problem is, I don't know what to do to achieve this. I've already used atan, math.tan and so many other functions but without any good results.
Could you help me? Thanks in advance.
Calculate a dot product of object vectors. Use Math.acos on the value you get. That will give you an angle in radians.
So, say your blue dot is at vec1 = (50, 100) and green one at vec2 = (100, 400).
A tuple (x, y) as a two dimensional vector describes object's position and distance from (0, 0) on your screen. To find the angle between these two vectors, you do a standard, binary dot product operation on them. This will get you a scalar (a value, cos(Theta)), but you want the inverse of it (acos) which is the angle you're looking for.
You can get a better understanding on the matter here
Suppose the coordinates of the blue and green points are (xblue, yblue) and (xgreen, ygreen) respectively.
The angle at which the blue point sees the green point is:
double angleRadians = Math.atan2(ygreen-yblue, xgreen-xblue);
If you want the angle in degrees:
double angleDegrees = Math.toDegrees(angleRadians);

Categories