Convert degree to radians in ruby - ruby

I have a latitude and longitude in degrees and I want to convert these into radians. How can I do that?
P.S. I am using sphinx search engine and it requires values in radians

Just the same way you convert degrees to radians in real life:
radians = degrees * Math::PI / 180

There are 360 degrees and 2 pi radians in a circle. So to convert degrees to radians, divide by 360 and multiply by 2 * pi (approx. 6.28).
Or equivalently, divide by 180 and multiply by pi.

Related

Tibia angle from Quaternion on a plane, Euler Angles

I came to a situation on getting Tibia angles from an IMU.
The sensor is giving me quaternions and also Euler Angles (order XYZ).
I need to know based on a reference plane, the Z angle on plane XZ (Directing z up)
My protocol is to get the person standing and get a calibrated quaternion from that position and then when the person walks I still need to know that angle based like if the sensor was still positioning that plane.
I came into an interesting paper that explains exactly my problem and application on equation 6.
For my understanding, I need to get a DCM matrix out of each measurement quaternion and then apply the directional unit vector from euler angles during calibration and apply to that matrix, then apply atan of division of component X and Z of the result of that multiplication.
Based on that my steps are:
1 - Get calibrated quaternion Q1 and calculate directional vector of my Euler angles.
2 - As the sensor measures, I take the Directional Cosine Matrix of Q1 apply to the calibrated direction vector my coordinate transformation
3 - calculate the Atan of components X and Z of that directional vector on sensor coordinate system.
However, I am getting different results and I am not understanding what is that equation really doing.
You are not looking for the twist angle but unit vectors on the quaternion coordinate system.
Take your calibrated roll, pitch and Yaw and save it as a unit vector (be aware that there are 12 ways to do this conversion and you might look at this link). If you say that its XYZ order then get this:
Mx[0,0] = Cosy * Cosz;
Mx[0,1] = -Cosy * Sinz;
Mx[0,2] = Siny;
Mx[1,0] = Cosz * Sinx * Siny + Cosx * Sinz;
Mx[1,1] = Cosx * Cosz - Sinx * Siny * Sinz;
Mx[1,2] = -Cosy * Sinx;
Mx[2,0] = -Cosx * Cosz * Siny + Sinx * Sinz;
Mx[2,1] = Cosz * Sinx + Cosx * Siny * Sinz;
Mx[2,2] = Cosx * Cosy;
Convert each quaternion of that same sensor into a DCM matrix
Multiply the direction vector into each DCM matrix
Now you have unit vector in all directions. In order to get angles you can get the Acos of the dot product of those vectors or calculate Atan(Dcmx/Dcmx) like the paper you shared

Issues finding outward facing angle between point on circle and center

I'm finding the angle between the centre of my circle and the triangle in degrees like so:
atan2((centre.y-triangle.y), (centre.x-triangle.x) * 180 / PI - 90
I'm setting the rotation of my triangle object which takes degrees as a parameter. The issue is all of my triangles are not rotated outwards correctly, which I presume is a result of the calculation of my position which is done like this:
triangle.x = -(width / 2) + (stage.width / 2) + radius * sin((index / total) * (2 * PI))
Here is an example of what happens, as you can see the last few triangles in the circle appear to be facing outwards correctly.
OK, I need some answer space to put all this info.
First of all you need to calculate the angle of a given triangle. You can do that with the following:
int angle = (360 / numberOfElements) * triangleIndex;
You also need to work out a "slice" (don't no what that is, just read it) to use for calculating the new positon:
var slice = (2 * Math.PI / numberOfElements) * triangleIndex;
Next, you need to work out the position of each triangle:
int tempRadius = radius + (int)(triangleHeight / 2);
int traingleCentreX = (int)(centre.X + tempRadius * Math.Cos(slice));
int traingleCentreY = (int)(centre.Y + tempRadius * Math.Sin(slice));
//assuming centre is the centre of the circle
[Credit for all this maths goes to this answer
]
Now that you have the correct position of each of your triangles, you should be able to apply the rotation (using angle) and it should look amaze-balls!
NOTE: Positions will be calculating starting at the right (i.e. 90 degrees). So when doing the rotation add an extra 90 degrees!
http://jsfiddle.net/TcENr/ (it as the quickest to test!)
The issue with the subtle offset of the rotation was because I wasn't adding the half width and height of the triangle to it's position, this fixed the problem:
rotation = atan2(centreY-(triangleY+triangleHalfHeight),centreX-(triangleX+triangleHalfWidth)) * 180 / Math.PI - 90;

Compute equidistant GPS point around a center

I have a question about some GPS calculations.
My problem is as follow :
I have a specific point P, and I want to compute N points around P.
Here is the algorithm :
P = (x, y) // latitude, longitude
N = 8
angle_size = 360/N
points = []
for i in 1..N
points.push compute_100meter(P, angle_size*i)
end
In this example, I'm trying to compute 8 equidistant point within 100 meter from P.
Is anyone know a ruby gem allowing me to do so ?
My problem is to write the content of compute_100meter
EDIT:
I have to take into account the earth curvature and get the point coordinates in degree (latitude, longitude).
As long as the radius is small enough (and 100 meters should be, unless you're right next to the north or south pole), a simple linear approximation should do well enough:
def perimeter_point(lat, lon, angle, radius)
# convert angle from degrees to radians
angle *= Math::PI / 180
# convert meters to degrees approximately, assuming spherical Earth
radius /= 6371000 * Math::PI / 180
# calculate relative length of the circle of longitude compared to equator
scale = Math.cos( lat * Math::PI / 180 );
# add offsets to longitude and latitude and return them
# (I'm assuming that angle = 0 means due east)
lat += radius * Math.sin(angle)
lon += radius * Math.cos(angle) / scale
return lat, lon
end
Note that, if your center point is near the 180th meridian, this could return longitudes below -180 or above +180. If that's a problem, check for it and normalize as needed. (Output latitudes outside the ±90 range are also technically possible, if the center point is near the north or south pole, but the approximation I used breaks down close to the poles anyway.)

Convert OpenGL 4x4 matrix to rotation angles

I am extracting in OpenGL the Model Matrix with
glGetFloatv (GL_MODELVIEW_MATRIX, (float*)x)
And would like to extract from the resulting 4x4 matrix the x,y and z axis rotations. How Can I do that ?
Thanks !
First you should know, that x,y,z axis rotations, called Euler Angles suffer from serious numerical problems. Also they're not unambigous. So either you store a rotation angle and the rotation axis, thus effectively forming a quaternion in disguise, or you stick with the full rotation matrix.
Find the quaternion from a rotation matrix is called an eigenvalue problem. Technically you're determining the eigenvector of the rotation matrix, which is the axis and the magnitude designates the angle.
I'm writing a CAD-like app, so I understand your problem, we 'in the business' know how awful Euler angles are for linear transformations - but the end-user finds them far more intuitive than matrices or quaternions.
For my app I interpreted Ken Shoemake's wonderful algorithm, it's one of the very few that support arbitrary rotation orders. It's from '93, so it's in pure C code - not for the faint hearted!
http://tog.acm.org/resources/GraphicsGems/gemsiv/euler_angle/
Something like this should give you what you're after.
final double roll = Math.atan2(2 * (quat.getW() * quat.getX() + quat.getY() * quat.getZ()),
1 - 2 * (quat.getX() * quat.getX() + quat.getY() * quat.getY()));
final double pitch = Math.asin(2 * (quat.getW() * quat.getY() - quat.getZ() * quat.getY()));
final double yaw = Math.atan2(2 * (quat.getW() * quat.getZ() + quat.getX() * quat.getY()), 1 - 2 * (quat.getY()
* quat.getY() + quat.getZ() * quat.getZ()));
I use this as a utility function to print out camera angles when I'm using SLERP to interpolate between 2 quaternions that I've derived from 2 4x4 matrices (i.e. camera movement between 2 3D points).

How to calculate the angle of a vector from the vertical?

Im trying to find out the angle (in degrees) between two 2D vectors. I know I need to use trig but I'm not too good with it. This is what I'm trying to work out (the Y axis increases downward):
I'm trying to use this code at the moment, but it's not working at all (calculates random angles for some reason):
private float calcAngle(float x, float y, float x1, float y1)
{
float _angle = (float)Math.toDegrees(Math.atan2(Math.abs(x1-x), Math.abs(y1-y)));
Log.d("Angle","Angle: "+_angle+" x: "+x+" y: "+y+" x1: "+x1+" y1: "+y1);
return _angle;
}
These are my results (There constant when providing a constant position, but when I change the position, the angle changes and I can't find any link between the two angles):
Position 1:
x:100 y:100
x1:50 y1:50
Angle: 45
Position 2:
x:92 y:85
x1:24 y1:16
Angle: 44.58
Position 3:
x:44 y: 16
x1:106 y1:132
Angle: 28.12
Edit: Thanks everyone who answered and helped me figure out that was wrong! Sorry the title and the question was confusing.
You first have to understand how to compute angle between two vectors and there are several of them. I will give you what I think is the simplest.
Given v1 and v2, their dot product is: v1x * v2x + v1y * v2y
The norm of a vector v is given by: sqtr(vx^2+vy^2)
With this information, please take this definition:
dot(v1, v2) = norm(v1) * norm(v2) * cos(angle(v1, v2))
Now, you solve for angle(v1, v2):
angle(v1, v2) = acos( dot(v1, v2) / (norm(v1) * norm(v2)) )
Finally, taking the definitions given at the beginning, then you end up with:
angle(v1, v2) = acos( (v1x * v2x + v1y * v2y) / (sqrt(v1x^2+v1y^2) * sqrt(v2x^2+v2y^2)) )
Again, there are many ways to do this, but I like this one because it is helpful for dot product given angle and norm, or angle, given vectors.
The answer will be in radians, but you know that pi radians (that is 3.14 radians) are 180 degrees, so you simply multiply by the conversion factor 180/pi.
Aha! Turns out I just needed to flip my angle and use atan2. This is my final code:
private float calcAngle(float x, float y, float x1, float y1)
{
float _angle = (float)Math.toDegrees(Math.atan2(x1-x, y-y1));
return _angle;
}
Thanks everyone for helping me figure this out and also for helping me to understand what I'm actually doing! :)
Do not take the absolute value of the arguments to atan2. The whole point of atan2 is that it uses the signs of its arguments to work out which qaudrant the angle is in. By taking the absolute values you are forcing atan2 to only return values between 0 and pi/2 instead of -pi to pi.
It looks like Niall figured it out, but I'll finish my explanation, anyways. In addition to explaining why the solution works, my solution has two advantages:
Potential division by zero within atan2() is avoided
Return value is always positive in the range 0 to 360 degrees
atan2() returns the counter-clockwise angle relative to the positive X axis. Niall was looking for the clockwise angle relative to the positive Y axis (between the vector formed by the two points and the positve Y axis).
The following function is adapted from my asteroids game where I wanted to calculate the direction a ship/velocity vector was "pointing:"
// Calculate angle between vector from (x1,y1) to (x2,y2) & +Y axis in degrees.
// Essentially gives a compass reading, where N is 0 degrees and E is 90 degrees.
double bearing(double x1, double y1, double x2, double y2)
{
// x and y args to atan2() swapped to rotate resulting angle 90 degrees
// (Thus angle in respect to +Y axis instead of +X axis)
double angle = Math.toDegrees(atan2(x1 - x2, y2 - y1));
// Ensure result is in interval [0, 360)
// Subtract because positive degree angles go clockwise
return (360 - angle) % 360;
}
It should be :
atan( abs(x1 - x)/abs(y1 - y) )
abs stands for absolute (to avoid negative values)
I believe the equation for the angle between two vectors should look more like:
toDegrees(acos((x*x1+y*y1)/(sqrt(x*x+y*y)*sqrt(x1*x1+y1*y1))))
Your above equation will calculate the angle made between the vector p1-p2 and the line made by extending an orthogonal from the point p2 to the vector p1.
The dot product of two vectors V1 and V2 is equal to |V1|*|V2|cos(theta). Therefore, theta is equal to acos((V1 dot V2)/(|V1||V2|)). V1 dot V2 is V1.xV2.x+V1.yV2.y.
The magnitude of V (i.e., |V|) is the pathogorean theorem... sqrt(V.x^2 + V.y^2)
My first guess would be to calculate the angle of each vector with the axes using atan(y/x) and then subtract those angels and take the absolute value, that is:
abs(atan(y/x) - atan(y1/x1))
Are you using integers? Cast the arguments as doubles, and I would use fabs on the result, not the arguments. The result will be in radians; to get degrees, use:
res *= (360.0/(2.0*Math.PI));
The angle of the second vector relative to the first = atan2(y2,x2) - atan2(y1,x1).
http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm

Resources