On my calculator I typed in 90-sin^-1(Y/X)
Y=6, X=9
I was returned with approximately:
48.71 degrees (which I expected)
But on java it returns:
0.72
I was told to use asin on java... Is that correct?
Yes, the asin method is correct for that.
The result from asin is in radians, so you need to convert it to degrees:
double angle = 90 - Math.toDegrees(Math.asin(Y / X));
trigonometric functions in programming languages return a value measured in radians. you need to convert to degrees like below.
degrees=radians*180/PI
Related
Given following problem:
I have 2 solutions:
First is to calculate difference in absolute angles, then renormalize angle. bad idea, 2 x atan2() is slow, renormalisation is inefficient.
angle = clamp_to_range( atan2(P1.y, P1.x) - atan2(P0.y, P0.x));
Second is to calculate dot product, normalize, calculate arccos(). Also bad idea, because angle sign will be incorrect.
angle = acos( dot(P0, P1) / sqrt( dot(P0,P0) * dot(P1, P1) ) );
I feel, that there should be some formula. How to solve given problem efficiently?
It is possible to use only one atan2 but both cross product and scalar product of vectors:
angle = atan2(Cross(P0, P1), Dot(P0, P1);
Do you really need the angle in radians / degrees, instead of as a unit vector or rotation matrix?
An xy unit vector can represent angle instead of absolute direction; the angle is the angle between the vertical (or horizontal) axis and the unit vector. Trig functions are very slow compared to simple multiply / add / subtract, and still slow compared to div / sqrt, so representing angles as vectors is usually a good thing.
You can calculate its components using the Cross(P0, P1) and Dot(P0, P1), but then normalize them into an xy unit vector instead of using atan2 on them.
See also Rotate Object Towards Direction in 2D on gamedev.SE, and Is it better to track rotation with a vector or a float?
This is easy to vectorize with SIMD, much moreso than a SIMD atan2. rsqrtps exists mostly to speed up x *= 1.0 / sqrt(foo) (and reusing the same multiplier for a SIMD vector of y values) for normalization. But rsqrtps is very low accuracy so you often need a Newton Raphson iteration to refine. The most recent CPUs (Skylake) have good FP sqrt / div throughput, so you could just normalize the naive way with _mm_sqrt_ps and leave optimization for later. See Fast vectorized rsqrt and reciprocal with SSE/AVX depending on precision.
I'm developing game in Game Maker kind of program (not actual Game Maker, though), because I've failed in coding games in real languages (can code normal apps, just not games) so many times.
Anyway, in program that I'm using direction function was proven to be buggy at times. However x and y speed of object are always correct, so I'd like to calculate direction angle (in degrees) from those. Unfortunately I'm not math genius and I'm always failing at trigonometry ;(. Can you help me?
My game making IDE's angle coordinate system is as follows:
270 deg.
180 deg. 0 deg.
90 deg.
Positioning system is like in most environments (0,0 in top-left)
Math libraries usually come with a function called atan2 just for this purpose:
double angle = atan2(y, x);
The angle is measured in radians; multiply by 180/PI to convert to degrees. The range of the angle is from -pi to pi. The 0-angle is the positive x-axis and the angle grows clockwise. Minor changes are needed if you want some other configuration, like the 0-angle being the negative y-axis and the range going from 0 to 359.99 degrees.
The main reason to use atan2 instead of atan or any of the other inverse trig functions is because it determines the correct quadrant of the angle for you, and you don't need to do it yourself with a series of if-statements.
Use the arctangent function. It should be something like this:
double direction(double x, double y) {
if (x > 0)
return atan(y/x);
if (x < 0)
return atan(y/x)+M_PI;
if (y > 0)
return M_PI/2;
if (y < 0)
return -M_PI/2;
return 0; // no direction
}
(Where x and y is the horizontal and vertical speed, M_PI is pi and atan is arctangent function.)
In game maker specifically you may use following:
direction = point_direction(x, y, x+x_speed, y+y_speed)
speed = point_distance(x, y, x+x_speed, y+y_speed)
(compare current and future x/y coordinates and return values)
Reverse the process to get x/y_speed:
x_speed = lengthdir_x(speed, direction)
y_speed = lengthdir_y(speed, direction)
Note: Added this post because its still viewed in relation to Game Maker:
Studio and its specific functions. Maybe it has no value for the person who
asked originally but i hope it will help some Game Maker users who wander here.
I have this bounding box expressed in latlong:
POLYGON ((51.2913 -13.5599, 51.2913 13.1589,
35.0325 13.1589, 35.0325 -13.5599, 51.2913 -13.5599))
widthDeg="26.7188" heightDeg="16.2588" areaDeg="434.4156254400001"
I'd like to get the equivalent width/height/area in metres.
I found this formula:
1 degree of longitude = 60 * 1.852 km * cos (latitude)
How can I use this to translate the bounding box? Is this a valid approximation?
Thanks for any hints!
Mulone
The width in metres may be different at the north and south sides of the bounding box; unless your box is guaranteed to be quite small in latitude, you probably don't really want to try to describe it with a height and width in metres.
The area is well defined, though; you can find a formula at Link: it's equivalent to |sin(lat1)-sin(lat2)| * |long1-long2| * R^2 if you measure your longitudes in radians. (Multiply by pi/180 if they're in degrees, and don't forget to convert them to radians before passing them to the sine function in that case.) Here R is the radius of the earth, which is approximately 6400km; more accurately 6371km; if you think you need it more accurately than that, remember that the earth isn't really a sphere and think again.
Hello all you math whizzes out there!
I am struggling with a math problem I am hoping you can help me with. I have calculated an angle of direction using radians. Within OpenGL ES I move my guy by changing my point value as such:
spriteLocation.x -= playerSpeed * cosf(playerRadAngle);
spriteLocation.y -= playerSpeed * sinf(playerRadAngle);
// playerRadAgnle is my angle of direction using radians
This works very well to move my sprite in the correct direction. However, I have decided to keep my sprite "locked" in the middle of the screen and move the background instead. This requires me to Reverse my calculated angle. If my sprite's direction in radians is equivalent to 90 degrees, I want to convert it to 270 degrees. Again, keeping everything in radians.
I will admit that my knowledge of Trig is poor at best. Is there a way to figure out the opposite angle using radians? I know I could convert my radians into degrees, then add/subtract 180 degrees, then convert back to radians, but I'm looking for something more efficient.
Thanks in advance....
-Scott
Add/subtract pi instead.
You need to add Pi and then use the remainder after division by 2 Pi (to make it restricted within [0; 2 Pi] range).
JavaScript:
function invertAngle(angle) {
return (angle + Math.PI) % (2 * Math.PI);
}
object_sprite.rotation = warp_direction - 3.14;
Given a "shape" drawn by the user, I would like to "normalize" it so they all have similar size and orientation. What we have is a set of points. I can approximate the size using bounding box or circle, but the orientation is a bit more tricky.
The right way to do it, I think, is to calculate the majoraxis of its bounding ellipse. To do that you need to calculate the eigenvector of the covariance matrix. Doing so likely will be way too complicated for my need, since I am looking for some good-enough estimate. Picking min, max, and 20 random points could be some starter. Is there an easy way to approximate this?
Edit:
I found Power method to iteratively approximate eigenvector. Wikipedia article.
So far I am liking David's answer.
You'd be calculating the eigenvectors of a 2x2 matrix, which can be done with a few simple formulas, so it's not that complicated. In pseudocode:
// sums are over all points
b = -(sum(x * x) - sum(y * y)) / (2 * sum(x * y))
evec1_x = b + sqrt(b ** 2 + 1)
evec1_y = 1
evec2_x = b - sqrt(b ** 2 + 1)
evec2_y = 1
You could even do this by summing over only some of the points to get an estimate, if you expect that your chosen subset of points would be representative of the full set.
Edit: I think x and y must be translated to zero-mean, i.e. subtract mean from all x, y first (eed3si9n).
Here's a thought... What if you performed a linear regression on the points and used the slope of the resulting line? If not all of the points, at least a sample of them.
The r^2 value would also give you information about the general shape. The closer to 0, the more circular/uniform the shape is (circle/square). The closer to 1, the more stretched out the shape is (oval/rectangle).
The ultimate solution to this problem is running PCA
I wish I could find a nice little implementation for you to refer to...
Here you go! (assuming x is a nx2 vector)
def majAxis(x):
e,v = np.linalg.eig(np.cov(x.T)); return v[:,np.argmax(e)]