Calculate path direction (azimuth) given starting and ending coordinates easily - iphone

I just trying know how to implement in objective c an equation that gave my position in lat, long and the position of a point in lat,long returns the relative angle to the azimuth so I will be able to know when to paint this point knowing the azimuth. I also know more or less the equation but I don´t know how to do it in objective c:
b = arccos ( cos (90 - lat2) * cos (90 - lat1) + sin (90 - lat2) * sin (90 - lat1) * cos (lon2 - lon1) )
A = arcsin ( sin (90 - lat2) * sin (lon2 - lon1) / sin (b) )

Regarding turning that equation into Objecive-C.
'man cos' and 'man sin' say they take radians, so you'll have to convert your degree values to radians. The common method seems to be this, (90 * M_PI/180), where 90 is the degree value being converted.
The functions for arccos and arcsin are acos and asin respectively. I assume they to take radians. Their man pages don't explicitly say.
Read the man pages to learn which version of the above functions are appropriate for your case. For instance, sin has; sin(), sinl(), sinf().

Related

What is the math behind FromToRotation? Unity3d

I'm trying to understand quaternions better, but I don't know how the math behind FromToRotation works. I tried looking this up but couldn't find any results.
You may know that a rotation can be represented by a quaternion of the following form:
cos (phi / 2)
sin (phi / 2) * axis.x
sin (phi / 2) * axis.y
sin (phi / 2) * axis.z
axis is the rotation axis and phi is the rotation angle. These are the two measures you need to define your quaternion.
There are multiple rotations that map a vector from to another vector to. The shortest rotation is the one where the axis is perpendicular to both of the vectors. Hence, the axis is:
axis = normalize(from x to)
x denotes the cross product.
And the angle is the angle between the two vectors:
phi = acos(dot(from, to) / (norm(from) * norm(to))
norm is the vector norm or vector length.
With these values, you can then calculate the quaternion.

Point of intersection between two vectors when the direction of one vector is not known

Problem: I have two vectors. I know the starting point of one vector, its direction, its magnitude. I know the starting point of the other vector and its magnitude. I need to find the direction of second vector as well as the position of intersection.
Vector A: Vector B:
Position = Known Position = Known
Direction= Known Direction= UNKNOWN
Magnitude= Known Magnitude= Known
To Find: Point of intersection.
Is it possible to find the point of intersection, with the given parameters? If so then how?
Application: I want to find the position where a player would be found based on the velocity he is moving, and shoot a bullet at him at the moment he would be found, taking into account the time taken for the bullet to reach that virtual target position.
Following on from the comments I'm going to take a leap here and answer your ultimate question directly.
Say the player is, at the initial time, at a point p and travelling with velocity v; your gun is at position q and shoots a bullet in any direction at speed s:
The length of OP is vΔt and that of Q sΔt. The angle a is given by the dot product:
We can then use the cosine rule to solve for Δt:
Written in this form, we can easily see that it is a quadratic equation, and thus directly solve for Δt using the Quadratic formula:
There are a few cases we need to consider here:
v < s: need to take the positive root only as otherwise we would get negative time.
v > s and dot(PQ, s) < 0: the bullet will never catch the player.
v > s and dot(PQ, s) > 0: take the negative root this time, as the positive root is for a backwards travelling player (longer time; this is also the case presented in the diagram above).
Having the correct value for Δt from above will then enable us to find the intersection point o, and therefore the intended direction d:
Note that d is not normalized. Also, this solution works for 3D too, unlike an approach with angles.
Let subscript 1 mark the player, and subscript 2 mark the AI:
initial: position (x_i, y_i)
angle: alpha_i
speed: u_i
The positions as a function of time t are :
player: (x_1 + u_1 * t * cos(alpha_1), y_1 + u_1 * t * sin(alpha_1))
AI's bullet: (x_2 + u_2 * t * cos(alpha_2), y_2 + u_2 * t * sin(alpha_2))
You have 2 uknowns:
t - the time of collision
alpha_2 - the angle the AI should shoot
The collision happens when Xs and Ys match. i.e.:
x_1 + u_1 * t * cos(alpha_1) = x_2 + u_2 * t * cos(alpha_2)
y_1 + u_1 * t * sin(alpha_1) = y_2 + u_2 * t * sin(alpha_2)
So,
alpha_2 = arcos( (x_1 + u_1 * t * cos(alpha_1) - x_2) / u_2 * t )
and also
alpha_2 = arcsin( (y_1 + u_1 * t * sin(alpha_1) - y_2) / u_1 * t )
substitue your values and equate these to expressions of alpha_2 to obtain t, then you can substitue t in either expression to obtain the angle alpha_2.

haversine / spherical law of cosines / vincenty in sql query

I'm testing out different formulas for finding specific points on the earth within a given radius from a given latitude/longitude. I've been using the 'spherical law of cosines' and what I believe to be an implementation of Haversine.
For the following formulas, these are the variables:
[$lat/$lon] = point of origin
[latitude/longitude] = second point
[$radius] = radius
Spherical law of cosines
3959 * acos( cos( radians('.$lat.') ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians('.$lon.') ) + sin( radians('.$lat.') ) * sin( radians( latitude ) ) ) ) <= '.$radius.';
Haversine (at least I think it is!)
3959*3.1415926*sqrt((latitude-'.$lat.')*(latitude-'.$lat.') + cos(latitude/57.29578)*cos('.$lat.'/57.29578)*(longitude-'.$lon.')*(longitude-'.$lon.'))/180) <= '.$radius.';';
I initially came across a lot of information saying that Haversine was the gold standard as far as accuracy. However, there also seems to be an opinion that the spherical law of cosines is more accurate than Haversine, as long as the distance being measured is greater than 5 metres or so. Furthermore, some say that Vincenty is said to trump both in accuracy.
Three questions:
Is my Haversine formula actually Haversine or it something else?
Any thoughts on which wins out for most accurate?
Can anyone provide me with a formulation for Vincenty along the lines of the above forumlas?
thanks!
Your so-called Haversine formula is totally incorrect.
Firstly it contains 7 left parentheses and 8 right parentheses.
Secondly conversion from degrees to radians is done in some cases by dividing by 57.29578 then there's a constant pi up the front and a constant 180 down the back.
Thirdly haversine(x) = sin(x / 2) ** 2 and I don't see the / 2 anywhere.
Fourthly there should be an asin function call near the front.
Correct formula here
My answer will be more Specific for your first and second answer
Q1: Is my Haversine formula actually Haversine or it something else?
I Don not understand Your haversine formula you made it
The write one or exactly the SQl query for haversine Formula is that
From Google Developer Site Click Here For Details
SELECT id, ( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) ) AS distance FROM markers HAVING distance < 25 ORDER BY distance LIMIT 0 , 20;
This SQL statement that will find the closest 20 locations that are within a radius of 25 miles to the 37, -122 coordinate. It calculates the distance based on the latitude/longitude of that row and the target latitude/longitude, and then asks for only rows where the distance value is less than 25, orders the whole query by distance, and limits it to 20 results. To search by kilometers instead of miles, replace 3959 with 6371.
You can make your Changes for this SQL query To be exactly What you want to.
Q2: Any thoughts on which wins out for most accurate?
There is no final answer for who can win?!, But we can deal with that:
1.Haversine is More Faster.
2.Spherical law of cosines is more accurate for Small distances.
And About Q3 I Know that the vincenty Formula is the most accurate But it is the slowest One

how can i get the sinf MATH functions answer in DEGREE?

For example,
sin 33.35 = 0.5523 in degree
sin 33.35 = 0.9347 in radian
As Xcode gives answers by default in radian.
So is there any way to get answer in degree ???
Yes, you multiply radians by a constant, 180/pi, to get degrees. That's because there are 2 * pi radians in a complete circle of 360 degrees (so half a circle is pi radians and 180 degrees).
Just keep in mind that's a conversion you have to apply to the input of the sine function (the angle), not the output (which is a length).
The pi constant can be used by including math.h and using the M_PI symbol.
A full circle in degrees exists of 360 degrees, and a full circle in radians is 2*pi. So, to convert radians to degrees, you divide by pi and multiply by 180.
radians * 180 / M_PI
If you would convert from degrees to radians, for example to provide degrees for a animation, use this:
degrees * M_PI / 180
I am using #DEFINEs for this myself:
#define DEGREES(radians)((radians)*180/M_PI)
#define RADIANS(degree)((degree)*M_PI/180)
Simply use by saying RADIANS(degree) or DEGREES(radians) in any part of your code, where you replace the degree and radians by the degree or radian value you had. This also keeps it more readable in my opinion if you are not used to radians.
Get the value in radians, then do:
CGFloat degrees = (radians * 180) / M_PI;
M_PI is a #define located in math.h.
Fortunately, the Objective-C language is a proper superset of C, which includes multiplication and division operators.

iphone compass tilt compensation

has anybody already programmed a iphone compass heading tilt compensation?
i have got some approaches, but some help or a better solution would be cool!
FIRST
i define a vector Ev, calculated out of the cross product of Gv and Hv. Gv is a gravity vector i build out of the accelerometer values and Hv is an heading vector built out the magnetometer values.
Ev stands perpendicular on Gv and Hv, so it is heading to horizonatl East.
SECOND
i define a vector Rv, calculated out of the cross product Bv and Gv. Bv is my looking vector and it is defined as [0,0,-1]. Rv is perpendicular to Gv and Bv and shows always to the right.
THIRD
the angle between these two vectors, Ev and Rv, should be my corrected heading. to calculate the angle i build the dot product and thereof the arcos.
phi = arcos ( Ev * Rv / |Ev| * |Rv| )
Theoretically it should work, but maybe i have to normalize the vectors?!
Has anybody got a solution for this?
Thanks, m01d
Yep. You DEFINITELY have to normalize.
This is from my code that I use to extract the orientation of the device.
Gravity is obtained as the x,y,z of the accelerometer
and compass is obtained from the x,y,z of the heading function
gravity.normalize();
compass.normalize();
compassEast=gravity.cross(compass);
compassEast.normalize();
compassNorth=compassEast.cross(gravity);
compassNorth.normalize();
Let me know if you need the full code.
Also, for those who havnt yet seen the iphone 4s gyroscope in action: its amazing! I swapped the above input to gravity and compass for the equivalents from the gyro and the result is stable and smooth and awesome :) Go Apple.
I didn't receive the source code but I set up my own example. You can see the project and code here: http://www.sundh.com/blog/2011/09/stabalize-compass-of-iphone-with-gyroscope/
yes, i did it like described above. but the result is not very accurate. i think with smoother accelerometer values it should work that way. because of this i have choosen to do the tilt compensation by adding/subtracting the accelermoter values of the corresponding axis to/from the compass values.
Here iss my code for the solution above, but its not a final working solution:
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading{
if (newHeading != nil) {
float Ax = accelerationValueX;
float Ay = accelerationValueY;
float Az = accelerationValueZ;
float filterFactor = 0.2;
Mx = [newHeading x] * filterFactor + (Mx * (1.0 - filterFactor));
My = [newHeading y] * filterFactor + (My * (1.0 - filterFactor));
Mz = [newHeading z] * filterFactor + (Mz * (1.0 - filterFactor));
float counter = ( -pow(Ax, 2)*Mz + Ax*Az*Mx - pow(Ay, 2)*Mz + Ay*Az*My );
float denominator = ( sqrt( pow((My*Az-Mz*Ay), 2) + pow((Mz*Ax-Mx*Az), 2) + pow((Mx*Ay-My*Ax), 2) ) * sqrt(pow(Ay, 2)+pow(-Ax, 2)) );
headingCorrected = (acos(counter/denominator)* (180.0 / M_PI)) * filterFactor + (headingCorrected * (1.0 - filterFactor));
}
...
}