views:

316

answers:

5

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

+5  A: 

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.

Xavier Ho
you say you don't need trig, then suggest using arctan...
jk
I said "You don't actually need trigs for this one", and "If the lines are not aligned to a convenient degree..." Please don't take my words out of context. `=]`
Xavier Ho
+1 for the edited bit. imho vector really is the way to go here whether you just need the special case or not.
jk
+1  A: 

It's quite easy if you know it is going to stay at 45 degrees. If the distance from 50, 250 is 20, then the dots are at (50 - (20*sqrt(2)), 250 - (20*sqrt(2))) and (50 + (20/sqrt(2)), 250 + (20/sqrt(2))).

Generally, the 20*sqrt(2) part of each should be replaced with (distance)*cos(angle) and distance*sin(angle). One is for the x coordinate and one for the y coordinate. (depending on which side you measure the angle from!)

In summary, you should use sin and cos. 45 degrees is a special case where sin and cos are both 1/sqrt(2) so it doesn't matter which way round you use them.

adamnfish
+2  A: 

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).

Edmund
+4  A: 

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.

Troubadour
+1. Rotating vectors is a much better, general solution.
Xavier Ho
I'm guessing the OP won't know that |Z| = sqrt(Z.x*Z.x + Z.y*Z.y)
jk
@jk: Heh, I read it as "the length of the vector", but thanks for pointing that out.
Xavier Ho
@Xavier: "... thanks for pointing that out". Sorry, is this your answer? Oh wait, it appears it is.
Troubadour
@Troubadour: Huh. Umm. How would I say it otherwise? I'm confused.
Xavier Ho
@Xavier: How would you say _what_ otherwise? There is nothing confusing here apart from your last comment.
Troubadour
@Troubadour: Sorry. I know my first comment sounded like I was replying to someone else as if this answer was mine. I was asking how I could phrase "thanks for pointing that out" in a different way.
Xavier Ho
+2  A: 

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.

IVlad