Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Missing Coordinates. Basic Trigonometry Help

please refer to my quick diagram attached below.

what i'm trying to do is get the coordinates of the yellow dots by using the angle from the red dots' known coordinates. assuming each yellow dot is about 20 pixels away from the x:50/y:250 red dot at a right angle (i think that's what it's called) how do i get their coordinates?

i believe this is very basic trigonometry and i should use Math.tan(), but they didn't teach us much math in art school.

alt text http://www.freeimagehosting.net/uploads/e8c848a357.jpg

like image 815
Chunky Chunk Avatar asked Jun 01 '10 11:06

Chunky Chunk


4 Answers

You don't actually need trigs for this one. Simply use slopes, or change in x and y.

Given a line of slope m = y/x, the line perpendicular to that line has slope -1/m, or -x/y.

The slope m between the red dots is -150/150, or -1/1. I noticed your positive y points down.

Therefore, the positive slope is 1/1. Both of your x and y changes at the same speed, with the same amount.

Once you know that, then it should be pretty easy to figure out the rest. Since they're aligned at 45 degrees angle, the edge ratio of the 45-45-90 triangle is 1 : 1 : sqrt(2). So if your length is 20, the individual x and y change would be 20/sqrt(2), or roughly 14 in integers.

So, your two yellow dots would be at (36, 236), and (64, 264). If the lines are not aligned to a convenient degree, you would have to use arctan() or something similar, and get the angle between the line and the horizontal line, so you can figure out the ratio of x and y change.

I hope my answer wasn't too hard to follow. For a more general solution, see Troubadour's answer.


Edit: Since the OP said the lower red dot is actually rotating around the upper red dot, we will need a more flexible solution instead.

I'm going to extend this answer from Troubadour's, since I'm doing exactly the same thing. Please refer to his post as you read mine.

1. Get the vector from origin (200, 100) to rotating point (50, 250):

vector = (200 - 50, 100 - 250) = (150, -150)

2. Rotate your vector by swapping the x and y, and negate x to get the new vector:

vector = (150, -150) => swap => (-150, 150) => negate x => (150, 150)

3. Get the unit vector (of length 1) from the new vector:

vector = vector / length(vector)
       = (150 / length(vector), 150 / length(vector))
       ~= (0.7071, 0.7071)

       where

       length(vector) = sqrt(150^2 + 150^2) ~= 212.2320

4. Get the displacement vector of length 20, by multiplying the unit vector.

displacement_vector = vector * 20 
                    = (0.7071 * 20, 0.7071 * 20)
                    = (14.1421, 14.1421)

5. Add/Subtract this vector to/from your rotating vector (point):

yellow_1 = (50, 250) + (14.1421, 14.1421) ~= (64, 254)
yellow_2 = (50, 250) - (14.1421, 14.1421) ~= (36, 236)

I hope the above steps help you with formulating your code. Doesn't matter what the angle it's at, same steps.

like image 89
Xavier Ho Avatar answered Nov 09 '22 07:11

Xavier Ho


Call the red dot at ( 50, 250 ) A and the one at ( 200, 100 ) B.

One way would be to first calculate the vector AB i.e.

v_AB = ( 200 - 50, 100 - 250 ) = ( 150, -150 )

You can generate a vector at right angles to that by swapping the components and reversing the sign of one of the two components. So

v_AB_perp = ( 150, 150 )

is a vector rotated by rotating v_AB clockwise as you look at it on screen. You can normalise this to get a unit vector by dividing through by the magnitude i.e.

v_AB_perp_normalised = v_AB_perp / |v_AB_perp|

To get the yellow points just multiply this up by your 20 pixels and add/subtract it on to the co-ordinates of A.

like image 37
Troubadour Avatar answered Nov 09 '22 09:11

Troubadour


Since the yellow dots are off at right angles from the red-red line, you can use something simpler. I won't answer the whole question but I'll try to give a few clues:

Ignoring the actual distance to the yellow dots, imagine some other dots on the same NW-SE line, the same distance away as that NE red dot. The vector to that is simply the vector to the red dot, rotated 90 degrees.

Rotating by 90 degrees can be done by swapping the coordinates and inverting one of them.

Once you have that, move that yellow dot to its closer position by scaling that vector by the real distance (20).

like image 2
Edmund Avatar answered Nov 09 '22 09:11

Edmund


This should work (I'll just refer to the left-most yellow point, but we'll get the coordinates of both in the end):

  1. Find the slope of the line given by the two red points.
  2. Find the equation of the line between the yellow point and the red point (d2).
  3. Find the coordinates of the yellow points by using the line equation d2 and the fact that the distance from the lowest red point is 20.

For 1:

Find the slope: m = (y1 - y2) / (x1 - x2) = (250 - 100) / (50 - 200) = 150 / -150 = -1

For 2:

We know that d1 (line between the red points) is perpendicular on d2 (line between red point and yellow point), and therefore the product of their slopes must be -1. Therefore, the slope of d2 is m = 1

Therefore the equation is: d2: y - 250 = x - 50 => d2: y - x = 200

For 3:

The required yellow point lies on the line d2, and its distance to the lowest red point is 20. Solve the system of equations:

y - x = 200
(x - 50)^2 + (y - 250)^2 = 400

The computation gets pretty ugly, but solving it with mathematica gives:

{{x -> 35.8579, y -> 235.858}, {x -> 64.1421, y -> 264.142}}

That's where your two yellow points lie!

Programmatically, you can solve such a system easily by substituting y = 200 + x in the second equation, then moving everything on one side and solving it as a quadratic equation.

like image 2
IVlad Avatar answered Nov 09 '22 09:11

IVlad