Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 13 years ago.
Improve this question
I'd like to create a function that calculates the distance between two pairs of lat/longs using the pythag theorem instead of the haversine great-circle formula. Since this will be over relative short distances (3km), I think this version that assumes a flat earth should be OK. How can I do this? I asked the internet and didn't come up with anything useful. :)
Thanks.
EDIT:
Here's what I came up with (seems to be working):
def get_dist(lat0, lng0, lat1, lng1)
begin
d_ew = (lng1.to_f - lng0.to_f) * Math.cos(lat0.to_f)
d_ns = (lat1.to_f - lat0.to_f)
d_lu = Math.sqrt(d_ew.to_f * d_ew.to_f + d_ns.to_f * d_ns.to_f)
d_mi = ((2*Math::PI*3961.3)/360)*d_lu
return d_mi
rescue Exception => ex
logger.debug "[get_dist] An exception occurred: #{ex.message}"
return -1
end
end
You can use a simple pythagoras triangle if you expect the distances involved to be small compared with the size of the Earth.
Suppose you are at (lat0, long0) and you want to know the distance to a point (lat1, long1) in "latitude units".
Horizontal (EW) distance is roughly
d_ew = (long1 - long0) * cos(lat0)
This is multiplied by cos(lat0) to account for longitude lines getting closer together at high latitude.
Vertical (NS) distance is easier
d_ns = (lat1 - lat0)
So the distance between the two points is
d = sqrt(d_ew * d_ew + d_ns * d_ns)
You can refine this method for more exacting tasks, but this should be good enough for comparing distances.
In fact, for comparing distances, it will be fine to compare d squared, which means you can omit the sqrt operation.
Well, since your points are near each other, the surface of the sphere is almost flat, so just find the coordinates of the points in 3D space, so find (x,y,z) for each of the points, where
x = r*sin(lat)*cos(long)
y = r*sin(lat)*sin(long)
z = r*cos(lat)
where r is the radius of the sphere.
or something like that depending on how you define lat/long. Once you have the two xyz coords, just use sqrt((x1-x2)^2+(y1-y2)^2+(z1-z2)^2). You really can't just use a 2D Pythagorean theoreom since you would need to get reasonable 2D coordinates, which is hard.
You will commonly see this notation 'dy, dx' which stands for difference y and difference x. You simply work out the differences on both axises, the get the square root of both differences squared as per the theorum.(the sum of the hype is equal to the square of the other two sides).
var dx:Number = x1-x2;
var dy:Number = y1-y2;
var distance:Number = Math.sqrt(dx*dx + dy*dy);
Hope this is clear enough
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 6 years ago.
Improve this question
Suppose if I have two vectors, A and B, and an axis (normalized vector), how do I find the angle between A and B such that the angle difference between A after rotation(axis, angle) and B wrt to the given axis is 0. A doesnt have to be equal to B after the rotation. Basically I want to find the angle difference between A and B in a specified plane.
Note: this is different than finding the shortest angle between 2 vectors since the axis is not the cross product between A and B. Thus, technique here (and many SO answers) does not apply. This needs to work in 3D.
I don't think the problem has a solution unless both A and B are the same length and A and B both make the same angle (in the usual sense of shortest angle between vectors) with the axis. I will assume that these are given.
In that case, one solution would be to compute the orthogonal projection of both A and B into a plane that is orthogonal to the axis. This could be done by subtracting the component that is in the direction of the axis. So if I have a unit vector in the direction of the axis and call it X, the computation would be something like
Aproj = A - dot(A, X)X
Bproj = B - dot(B, X)X
Then the angle between Aproj and Bproj (in the usual sense of shortest angle) is the angle of rotation around the axis that you are asking about.
I'm not sure if this is the simplest way to compute it, but it should work pretty generally.
The dot product give the angle between A & B.
In Fortran something like: dotAB = DASIN(DOT(A/|A|, B/|B|)).
A cross product gives a vector orthongal to A and B.
The projection of the Xproduct-vector towards the planes (or axis) should get you there when multiplied by the angle DotAB. You'll probably be a sine or cosine in there.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
I need to calculate circumcenter coordinates (or at least I hope they're called that) at point C for an isosceles triangle (the circle must be such, that created triangle is). I know the point O (origin), two vectors p and q (length may differ) originating in that point (leading to points P and Q). I also know the radius r of this to be circumscribed circle. When the circle's center is known it should create said green highlighted isosceles triangle. Here is drawing for better understanding:
Update (solution):
Calculates the length of p and q vectors
Normalize them both, and add them together
Normalize this to be OC vector again
Finally extend OC vector from point of origin O to length equivalent to radius r
Thinking geometrically:
normalise vectors p and q, i.e. p = p / |p|, q = q / |q|
add them together
normalise the result
multiply that by r - this is the vector OC
add to O
Steps 1 - 3 simply produce the bisection of the vectors p and q
EDIT this is simplified somewhat compared to my original answer.
The first equation of your system is:
(x_c-x_o)^2 + (y_c-y_o)^2 = r^2
The second one is more convoluted. You must intersect the circumference
(x-x_c)^2+(y-y_c)^2 = r^2
with your two vectors, that have equation rispectively
y = (Q_y/Q_x)*x and y = (P_y/P_x)*x
this gives you the two points of intersection p and q in function of x_c and y_c. Now force hte distance OP and OQ to be equal (you want an isoscele triangle), and you have your second equation.
Solve hte two equation system and you have the formula for x_c and y_c.
Assuming i did the math right, the solution is:
x_c = ((a+b)^2 * r^2) / ((a+b)^2+4)
y_c = (-2*(a+b) * r^2) / ((a+b)^2+4)
where
a = p_y / p_x
b = q_y / q_x
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Create random number within an annulus
I would like to obtain a uniformly obtained random point within an annulus, that is, the area that lies inside a circle of radius R1, but outside a circle of radius R2, where R1 > R2 and both circles are centered at the same point. I would like to avoid using rejection sampling.
If possible, I would like the solution to be similar to this one —used for calculating random points within a circle— which I find it extremely elegant and intuitive. That is, I would also like to avoid using the square root.
Its very easy. Use polar coordinates, i.e. you generate one random value for the angular value theta, and one for the distance from the origin. As your circles are both at the same origin this gets very easy.
BUT ATTENTION: you can generate the theta value by a uniform random function, that is fine, but for the distance you cant do that, as then the points will cluster around the origin.
You have to take into consideration that the perimeter of a circle grows in ^2 (you have to use the inverse which is the square root).
Using a uniform distributed random function rnd (0..1) it would be like this:
theta = 360 * rnd();
dist = sqrt(rnd()*(R1^2-R2^2)+R2^2);
EDIT: For conversion into cartesion coordinates, you just compute:
x = dist * cos(theta);
y = dist * sin(theta);
EDIT: Please note that this solution might not be uniform. See comments by Mark Dickinson below.
Ok, I think I figured it out. Note that this solution is heavily inspired in this answer, and that r1 = R1/R1 and r2 = R2/R1.
Pseudo-code:
t = 2*pi*random()
u = random()+random()
r = if u>1 then 2-u else u
r = if r<r2 then r2+r*((R1-R2)/R2) else r
[r*cos(t), r*sin(t)]
Here it is in Mathematica.
f[] := Block[{u, t, r}, u = Random[] + Random[];
r1 = 1; r2 = 0.3;
t = Random[] 2 Pi;
r = If[u > 1, 2 - u, u];
r = If[r < r2, r2 + r*((R1 - R2)/R2), r];
{r Cos[t], r Sin[t]}]
ListPlot[Table[f[], {10000}], AspectRatio -> Automatic]
What it does is to remap all the numbers falling inside the inner circle into the annulus, spreading them evenly. If somebody finds a problem regarding the uniformity of this solution please comment.
Compare with this other solution found here:
The easiest way to do this is to use rejection sampling. Generate a large number of points uniformly in a square of side length 2*R2, then filter those samples to those inside the outer circle and not in the inner circle.
Not pretty or efficient, but in most cases, sufficient.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
This is not homework. We are trying to build double connection lines between circles for a project.
Given a triangle of any type (because it will be rotated)
AB is known
AC is known
BC is known Where
AB is equal to BC (they are both the radius of the circle)
Point A is (x1,y1) and is known. It is the center point of the circle.
Point B is (x2,y2) and is known. It is the point on the edge of the circle that connects to the center of a remote circle.
Point C is unknown (x3,y3) and is what we are trying to figure out. I THINK we need to use the law of cosines, but it's not working out so far.
Thanks to anyone who can help!
You have much more info than you need to get the answer and it has nothing to do with law of cosine
Basically you only need A, B, AC, and BC
You draw a circle with A as the center and AC as the edge
You draw another circle with B as the center and BC as the edge
These two circles will have two intersecting points, and they are the two possible location of C
put it in math:
you have two Binary quadratic equations:
(x-x1)^2 + (y-y1)^2 = AC^2
(x-x2)^2 + (y-y2)^2 = BC^2
and you need to get (x, y) from these two equations
You can use the law of cosines, since you know the lengths of the three sides of the triangle (AB), (BC) and (AC). The law of cosines states that
(BC)^2 = (AC)^2 + (AB)^2 - 2 (AC)(AB) cos theta
where theta is the internal angle of the triangle at vertex A. Rearranging this gives
theta = acos(((BC)^2 - (AC)^2 - (AB)^2)/(-2 (AC)(AB)))
then your answer is (in vector notation):
(x,y) = (x1,y1) + (AC)*(v1,v2)
where (v1,v2) is the unit vector in the direction from A to C. (i.e., in scalar notation, x=x1+(AC)*v1 and y=y1+(AC)*v2). We can obtain v1 and v2 by rotating the unit vector from A to B by the angle theta:
v1 = (cos(theta)*(x2-x1) + sin(theta)*(y2-y1))/(AB)
v2 = (cos(theta)*(y2-y1) - sin(theta)*(x2-x1))/(AB)
Flip the sign of theta to get the other of the two solutions.
Note that one can avoid ever calculating theta by observing that:
cos(theta) = ((BC)^2 - (AC)^2 - (AB)^2)/(-2 (AC)(AB))
sin(theta) = sqrt(1-((BC)^2 - (AC)^2 - (AB)^2)/(-2 (AC)(AB))^2)
which may be faster to evaluate than the trigonometric functions.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 11 years ago.
Improve this question
Image of the problem at:
In my code I have 4 points: Q, R ,S , T.
I know the following
Coordinates for R, T, and S;
That segment RT < RQ < RS;
I need to figure out the coordinates of Q.
I already know point Q can be found on the line segment TS. However I need to get the coordinates for Q and I need it to be a relatively efficient calculation.
I have several solutions for this problem but they are all so convoluted and long I know I must be doing something wrong. I feel certain there must a simple elegant way to solve this. The best solution would be one that minimizes the number of more intensive calculations but that also isn't ridiculously long.
Q is the intersecting point between a circle of radius d around R and the line TS, which leads to a quadratic equation with a number of parameters in the coefficients. I don't know if the following if “the best” solution (it may even be better to use a numerical solver in between), but it is completely worked out. Because I think it's more readable, I've changed your coordinate names to put T at (T1, T2), S at (S1, S2) and, to keep the formulas shorter, R at (0, 0) – just adjust S and T and the returned values accordingly.
tmp1 = S1^2 - S2*T2 - S1*T1 + S2^2;
tmp2 = sqrt(- S1^2*T2^2 + S1^2*d^2 + 2*S1*S2*T1*T2 - 2*S1*T1*d^2 -
S2^2*T1^2 + S2^2*d^2 - 2*S2*T2*d^2 + T1^2*d^2 + T2^2*d^2);
tmp3 = S1^2 - 2*S1*T1 + S2^2 - 2*S2*T2 + T1^1 + T2^2;
t = (tmp1 + tmp2)/tmp3;
if (0 > t || t > 1) {
// pick the other solution instead
t = (tmp1 - tmp2)/tmp3;
}
Q1 = S1+t*(T1-S1);
Q2 = S2+t*(T2-S2);
Obviously, I take no warranties that I made no typos etc. :-)
EDIT: Alternatively, you could also get a good approximation by some iterative method (say, Newton) to find a zero of dist(S+t*(T-S), R)-d, as a function of t in [0,1]. That would take nine seven multiplications and one division per Newton step, if I count correctly. Re-using the names from above, that would look something like this:
t = 0.5;
d2 = d^2;
S1T1 = S1 - T1;
S2T2 = S2 - T2;
do {
tS1T1 = S1 - t*S1T1;
tS2T2 = S2 - t*S2T2;
f = tS1T1*tS1T1 + tS2T2*tS2T2 - d2;
fp = 2*(S1T1*tS1T1 + S2T2*tS2T2);
t = t + f/fp;
} while (f > eps);
Set eps to control your required accuracy, but do not set it too low – computing f does involve a subtraction that will have serious cancellation problems near the solution.
Since there are two solutions Q on the (TS) line (with only one solution between T and S), any solution probably involves some choice of sign, or arccos(), etc.
Therefore, a good solution is probably to put Q on the (TS) line like so (with vectors implied):
(1) TQ(t) = t * TS
(where O is some origin). Requiring that Q be at a distance d from R gives a 2nd degree equation in t, which is easy to solve (again, vectors are implied):
d^2 = |RQ(t)|^2 = |RT + TQ(t)|^2
The coordinates of Q can then be obtained by putting a solution t0 into equation (1), via OQ(t0) = OT + TQ(t). The solution 0 <= t <= 1 must be chosen, so that Q lies between T and S.
Now, it may happen that the final formula has some simple interpretation in terms of trigonometric functions… Maybe you can tell us what value of t and what coordinates you find with this method and we can look for a simpler formula?