Angles in Matlab - matlab

i need to calculate some expression for all angles from 0 to 90 degrees increments 10 degrees (of cause expression depends on some trigonometrical function).
It looks like:
for alpha = 0:10:90
func(alpha) = c * sin(alpha)
end
Who know how to work with degrees, tell, please

It should be:
for 0:pi/18:pi/2

Related

cardinal components to cardinal direction using arctan function

I have ocean currents data (going towards). what would be the conversion I can use?
270-(atan2(zonal,meridional)(180/pi)) or 270-(atan2(meridional,zonal)(180/)) or anything entirely different?
I have gone through [this link][1] and also [eol][2] website. I still have no idea.
using unit circle and arctan function I tried to do, like for first quadrant zonal component(x) towards east-west is positive and meridioanl component(y) north-south is positive I used arctan(x,y) to find the direction.
then for 2nd quadrant 90+arctan(x,y) ???
3rd quadrant 180+arctan(x,y) ??
4th quadrant 270+arctan(x,y) ??
please correct me if I am wrong...
Not sure what are you exactly asking, but the function atan2 already gives you the correct quadrant, so no special tricks must be done adding or substracting angles to the result.
If you write help atan2 you will see that it expects two parameters: y and x (in this order) and returns you an angle in radians with a range [-pi,+pi]
Eg.
rad2deg(atan2(1,1)) gives you 45 as result
rad2deg(atan2(-1,1)) gives you -45 as result
rad2deg(atan2(1,-1)) gives you 135 as result
rad2deg(atan2(-1,-1)) gives you -135 as result
EDIT:
if you want only positive angles, just do:
angle = atan2(Y, X);
if (angle < 0)
angle = angle + 2*pi;
end

Math function returns wrong value

I have the following calculations:
let sinX = sin(150.0) //returns -0,71487
let cosY = cos(150.0) // returns 0,699250
But the real values for sinX = 0,5 and for cosY = -0,86.
Does anybody know where is the error?
The calculation is correct. However sin and cos take their param in radians, not degrees.
In calculus and most other branches of mathematics beyond practical
geometry, angles are universally measured in radians. One radian is
equal to 180/π degrees.
To convert from radians to degrees, multiply by 180/π.
https://en.wikipedia.org/wiki/Radian
And are you sure the sin & cos methods haven't been redefined by creating or overriding the default methods. That happens in programming. If so, you might want to re-check your operation.

calculate the angle between 2 vectors, clockwise and from 0 to 2*pi

I have two (2-D) vectors with a common vertex ( I had made these 2 vectors out of 3 given points ) . I want to find the angle between them, from 0 to 2*pi, and I need it clockwise and positive. I currently use this:
v1=[x1 y1]-[X Y];
v2=[x2 y2]-[X Y];
ang = mod(atan2(v1(1)*v2(2)-v2(1)*v1(2),v1(1)*v2(1)+v1(2)*v2(2)),2*pi);
if ang==0
Angle=ang;
else
Angle=360 - (ang*180/pi); % change Radian to Degree
end
Although it works correctly, I was wondering if there is any better way to find the angle, maybe not using if/else??!
Thanks in advance
I assume you want to restrict the output to the half-open interval [0, 360). In that case, simply do the mod at the end, after your other conversions, no if required:
ang = atan2(v1(1)*v2(2)-v2(1)*v1(2),v1(1)*v2(1)+v1(2)*v2(2));
Angle = mod(-180/pi * ang, 360);
The clockwise angle is the exact opposite from what atan2 assumes, so you just have to negate it:
Angle = mod(-atan2(v1(1)*v2(2)-v1(2)*v2(1), v1*v2'), 2*pi) * 180/pi;
which is, in essence, identical to Bas' answer I see now :)

How can I correctly calculate the direction for a moving object?

I'm solving the following problem: I have an object and I know its position now and its position 300ms ago. I assume the object is moving. I have a point to which I want the object to get.
What I need is to get the angle from my current object to the destination point in such a format that I know whether to turn left or right.
The idea is to assume the current angle from the last known position and the current position.
I'm trying to solve this in MATLAB. I've tried using several variations with atan2 but either I get the wrong angle in some situations (like when my object is going in circles) or I get the wrong angle in all situations.
Examples of code that screws up:
a = new - old;
b = dest - new;
alpha = atan2(a(2) - b(2), a(1) - b(1);
where new is the current position (eg. x = 40; y = 60; new = [x y];), old is the 300ms old position and dest is the destination point.
Edit
Here's a picture to demonstrate the problem with a few examples:
In the above image there are a few points plotted and annotated. The black line indicates our estimated current facing of the object.
If the destination point is dest1 I would expect an angle of about 88°.
If the destination point is dest2 I would expect an angle of about 110°.
If the destination point is dest3 I would expect an angle of about -80°.
Firstly, you need to note the scale on the sample graph you show above. The x-axis ticks move in steps of 1, and the y-axis ticks move in steps of 20. The picture with the two axes appropriately scaled (like with the command axis equal) would be a lot narrower than you have, so the angles you expect to get are not right. The expected angles will be close to right angles, just a few degrees off from 90 degrees.
The equation Nathan derives is valid for column vector inputs a and b:
theta = acos(a'*b/(sqrt(a'*a) * sqrt(b'*b)));
If you want to change this equation to work with row vectors, you would have to switch the transpose operator in both the calculation of the dot product as well as the norms, like so:
theta = acos(a*b'/(sqrt(a*a') * sqrt(b*b')));
As an alternative, you could just use the functions DOT and NORM:
theta = acos(dot(a,b)/(norm(a)*norm(b)));
Finally, you have to account for the direction, i.e. whether the angle should be positive (turn clockwise) or negative (turn counter-clockwise). You can do this by computing the sign of the z component for the cross product of b and a. If it's positive, the angle should be positive. If it's negative, the angle should be negative. Using the function SIGN, our new equation becomes:
theta = sign(b(1)*a(2)-b(2)*a(1)) * acos(dot(a,b)/(norm(a)*norm(b)));
For your examples, the above equation gives an angle of 88.85, 92.15, and -88.57 for your three points dest1, dest2, and dest3.
NOTE: One special case you will need to be aware of is if your object is moving directly away from the destination point, i.e. if the angle between a and b is 180 degrees. In such a case you will have to pick an arbitrary turn direction (left or right) and a number of degrees to turn (180 would be ideal ;) ). Here's one way you could account for this condition using the function EPS:
theta = acos(dot(a,b)/(norm(a)*norm(b))); %# Compute theta
if abs(theta-pi) < eps %# Check if theta is within some tolerance of pi
%# Pick your own turn direction and amount here
else
theta = sign(b(1)*a(2)-b(2)*a(1))*theta; %# Find turn direction
end
You can try using the dot-product of the vectors.
Define the vectors 'a' and 'b' as:
a = new - old;
b = dest - new;
and use the fact that the dot product is:
a dot b = norm2(a) * norm2(b) * cos(theta)
where theta is the angle between two vectors, and you get:
cos(theta) = (a dot b)/ (norm2(a) * norm2(b))
The best way to calculate a dot b, assuming they are column vectors, is like this:
a_dot_b = a'*b;
and:
norm2(a) = sqrt(a'*a);
so you get:
cos(theta) = a'*b/(sqrt((a'*a)) * sqrt((b'*b)))
Depending on the sign of the cosine you either go left or right
Essentially you have a line defined by the points old and new and wish to determine if dest is on right or the left of that line? In which case have a look at this previous question.

Is there a fast way to calculate the smallest delta between two rotation values?

There are two views:
viewA and viewB. Both are rotated.
The coordinate system for rotation is weird: It goes from 0 to 179,999999 or -179,99999 degrees. So essentially 179,99999 and -179,99999 are very close together!
I want to calculate how much degrees or radians are between these rotations.
For example:
viewA is rotated at 20 degrees
viewB is rotated at 30 degrees
I could just do: rotationB - rotationA = 10.
But the problem with this formula:
viewA is rotated at 179 degrees
viewB is rotated at -179 degrees
that would go wrong: rotationB - rotationA = -179 - 179 = -358
358 is plain wrong, because they are very close together in reality. So one thing I could do maybe is to check if the absolute result value is bigger than 180, and if so, calculate it the other way around to get the short true delta. But I feel this is plain wrong and bad, because of possible floating point errors and unprecision. So if two views are rotated essentially equally at 179,99999999999 degrees I might get a weird 180 or a 0 if I am lucky.
Maybe there's a genius-style math formular with PI, sine or other useful stuff to get around this problem?
EDIT: Original answer (with Mod) was wrong. would have given 180 - right answer in certain circumstances (angles 30 and -20 for example would give answer of 130, not correct answer of 50):
Two correct answers for all scenarios:
If A1 and A2 are two angles (between -179.99999 and 179.99999,
and Abs means take the Absolute Value,
The angular distance between them, is expressed by:
Angle between = 180 - Abs(Abs(A1 - A2) - 180)
Or, using C-style ternary operator:
Angle between = A1 < 180 + A2? A1 - A2: 360 + A1 - A2
Judging from the recent questions you've asked, you might want to read up on the unit circle. This is a fundamental concept in trigonometry, and it is how angles are calculated when doing rotations using CGAffineTransforms or CATransform3Ds.
Basically, the unit circle goes from 0 to 360 degrees, or 0 to 2 * pi (M_PI is the constant used on the iPhone) radians. Any angle greater than 360 degrees is the same as that angle minus a multiple of 360 degrees. For example, 740 degrees is the same as 380 degrees, which is the same as 20 degrees, when it comes to the ending position of something rotated by that much.
Likewise, negative degrees are the same as if you'd added a multiple of 360 degrees to them. -20 degrees is the same as 340 degrees.
There's no magic behind any of these calculations, you just have to pay attention to when something crosses the 0 / 360 degree point on the circle. In the case you describe, you can add 360 to any negative values to express them in positive angles. When subtracting angles, if the ending angle is less than the starting angle, you may also need to add 360 to the result to account for crossing the zero point on the unit circle.
Let's try this again:
There are two angles between A and B. One of them is
θ1 = A - B
The other is
θ2 = 360 - θ1
So just take the minimum of those two.
In addition to Brad Larson's excellent answer I would add that you can do:
CGFloat adjustAngle(angle) { return fmod(angle + 180.0, 360.0); }
...
CGFloat difference = fmod(adjustAngle(angle1) - adjustAngle(angle2), 360.0);
Take the difference, add 360, and mod by 360.