Find number of degrees to rotate? - java

I am trying to find a method which will rotate an object to make it face a specified point, however the numbers I am getting don't make much sense and I don't think I understand what the math methods are returning.
Here is my code:
public void rotate(double x, double y) {
rotateRight(Math.toDegrees(Math.atan2((x - getX()), (y - getY()))));
}
x and y are the specified point and getX() and getY() are the objects current point, so I am trying to find the number of degrees that object has to turn right to be facing the specified point.
Can anyone recommend a reliable way to do this?

You need a matrix transformation to do it properly.

Your naming is a bit confusing, so I'm making some assumptions here. Your "object" is located at the origin (0,0) and getX() and getY() return the point that the object is currently facing, and you want the object to face a new point.
From here it's simple trig and arithmetic. First thing is to figure out your current angle:
current_angle=atan(getX()/getY())
Your new angle will be
new_angle=atan(newX/newY)
and the angle you need to rotate through is naturally,
rotation_angle=new_angle - current_angle

It depends on what units you are using. Personally, in radians, i have this function in my snippets.
public static double getAngleBetween(double x1, double y1, double x2, double y2)
{
return(Math.atan2(y1-y2, x1-x2));
}
Which results in the angle (in radians) between any two abstract points.

The angle returned by Math.atan2() is absolute. In order to turn it into a relative rotation you first need to know what the current angle is, then you need to subtract the two.

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.

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.

Determine if vertex is convex. Help understanding

I am studying the following code.
boolean convex(double x1, double y1, double x2, double y2,
double x3, double y3)
{
if (area(x1, y1, x2, y2, x3, y3) < 0)
return true;
else
return false;
}
/* area: determines area of triangle formed by three points
*/
double area(double x1, double y1, double x2, double y2,
double x3, double y3)
{
double areaSum = 0;
areaSum += x1 * (y3 - y2);
areaSum += x2 * (y1 - y3);
areaSum += x3 * (y2 - y1);
/* for actual area, we need to multiple areaSum * 0.5, but we are
* only interested in the sign of the area (+/-)
*/
return areaSum;
}
I do not understand the concept that area being negative.
Shouldn't area be always positive? maybe I am lacking some understanding of terms here.
I tried to contact the original writer but this code is about 8 years old and I have no way to contact the original writer.
This method of determining if the given vertex x2y2 is convex seems really mobile. I really want to understand it.
Any direction or reference to help me understand this piece of code will be appreciated greatly.
Source code : http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/applets/BruteForceEarCut.java
The algorithm use a very simple formula with which you can compute twice the area of a triangle.
This formula has two advantages:
it doesn't require any division
it returns a negative area if the point are in the counterclockwise order.
In the code sample, the actual value of the area doesn't matter, only the sign of the result is needed.
The formula can also be used to check if three points are colinear.
You can find more information about this formula on this site : http://www.mathopenref.com/coordtrianglearea.html
This algorithm is basically using the dot product of two vectors and interpreting the results. This is the core of the Gift Wrapping Algorithm used to find convex hulls.
Since a dot b is also equal to |a|*|b|*cos(theta) then if the result is positive, cos of theta must be positive and thus convex. Per a wiki article on cross products...
Because the magnitude of the cross product goes by the sine of the
angle between its arguments, the cross product can be thought of as a
measure of ‘perpendicularity’ in the same way that the dot product is
a measure of ‘parallelism’. Given two unit vectors, their cross
product has a magnitude of 1 if the two are perpendicular and a
magnitude of zero if the two are parallel. The opposite is true for
the dot product of two unit vectors.
The use of "area" is slightly misleading on part of the original coder in my opinion.
You know about how integrals work, right? One way to think of integrals is in terms of the area under the integrated curve. For functions that are strictly positive, that definition works great, but when the function becomes negative at some point, there is a problem because then you have to take the absolute value, right?
That is not always so, actually, and it can be quite useful in some contexts to leave the curve negative. Think back to what was said earlier: the area under the curve. All that space between negative infinity and our function. Clearly, that is absurd, right? A better way to think of it is as the difference between the area under the curve, and the area under the x axis. That way, when the function is positive, our curve is gaining more area, and when it is negative, it is gaining less than the x axis.
The same thing applies to plane figures that are not strict functions. In order to really determine this, we have to define which direction our edge is going as it travels around the figure. We can define it so that all the area on the right of our curve is inside the region, and all the area to the left is outside (or we can define it the other way around, but I will use the first way).
So our figure includes all the area from there to the edge at infinity of the plane that is directly to our right. Regions enclosed clockwise really include their conventional interior twice. Regions enclosed counterclockwise don't include their conventional interior at all. The area, then, is the difference between our region and the whole plane.
The application of this to concavity is fairly simple, if you understand what it actually means to be concave or convex. The triangle you are given is concave if it is cutting an area out from the plane, and it is convex if you are adding extra area to it. That is the exact same thing we were doing to determine the our area, so positive area corresponds to a convex shape, and negative area corresponds to a concave shape.
You can also do other weird things with this conceptual model. For instance, you can turn a region 'inside out' by reversing the edge direction.
I'm sorry if this has been a little hard to follow, but this is the actual way I understand negative area.

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