Click to See Complete Forum and Search --> : move line on trajectory


phm
September 2nd, 2005, 07:21 PM
Hi

1. I have to draw a line from point P1(x1,y1) to point P2(x2,y2).
2. If I drag/move the line, it should move only on a trajectory defined by its perpendiculars on P1 and P2(these 2 perpendiculars to initial line are obviously parallel one to another) , and not elsewhere.

How can I compute the trajectory points while mouse moves?

Thanks in advance

philkr
September 4th, 2005, 05:23 PM
You first compute the gradient of the line: m = (y2 - y1) / (x2 - x1)
The gradient of the perpendicular is: m' = -1/m
Move it this way: NewPositionY = OldPositionY + m' * CursorMovementX

andytim
September 5th, 2005, 03:05 AM
This is only a much easy math problem :rolleyes:
If you can attach a screen shot,maybe I can help you.

Jack

---------------------------------------------------------------------------------
XD++ MFC/C++ Flow/Diagram Library (Full Visio 2003 Like,100% Source Code Kit) -- http://www.********.net

phm
September 5th, 2005, 09:32 PM
You first compute the gradient of the line: m = (y2 - y1) / (x2 - x1)
The gradient of the perpendicular is: m' = -1/m
Move it this way: NewPositionY = OldPositionY + m' * CursorMovementX

Thank you for your reply.
Can you please provide me a bit of code to see the exact x&y values?
Thanks in advance.

philkr
September 6th, 2005, 05:34 AM
An example:
Say you have a line with P1(1,1) and P2(3,2).
The gradient is: m = (2 - 1) / (3 - 1) = 1 / 2 = 0.5
The gradient of the perpendicular is = - 1/0.5 = -2

Now if you move the cursor 10 pixels to the right for example:
You first simply add the 10 to the x values:
NewP1(1+10,Y) = NewP1(11, Y)
NewP2(3+10,Y) = NewP2(13, Y)

Then you have to calculate the new y-values:
NewY1 = 1 + (-2) * 10 = 1 - 20 = -19
NewY2 = 2 + (-2) * 10 = 2 - 20 = -18

The new line is given by NewP1(11,-19) and NewP2(13, -18)

ATTENTION: Now that I made the example, I found one error: This way is right for a normal coordinate system. But on the screen the y-value becomes smaller when you go up. So you will have to adjust the equations a bit:

m = (y1 - y2) / (x2 - x1) ---> y1 and y2 switched
NewPositionY = OldPositionY - m' * CursorMovementX ----> '-' instead of '+'

I hope this is right now. You can also use the old equations, but then you have to convert the y values this way: y' = ScreenHeight - y
And the same way back after calculation: y = ScreenHeight - y'

phm
September 6th, 2005, 01:05 PM
Hi

The line moves correctly on X, but on Y it still have strange behaviour. The angle varies from 60 to 90.
I did the test in OnMouseMove().

Thanks

philkr
September 7th, 2005, 04:02 AM
I must have made a mistake somewhere, but I don't see where. What I can say is that the gradient of the line is m = (y2 - y1) / (x2 - x1) in a kartesian coordinate system and m' = -1/m. As I already said the problem is that the screen is not in kartesian coordinates. The y value is 'upside-down'. It seems that my solution to this problem does not work. Hopefully you can find out yourself. Sorry I couldn't help you further.

EDIT: Wait! Now I know what I was missing. The 'b'-value. You get it from your original line with "b = y - m * x". Then you have the equation for the perpendicular with "y' = m' * x + b". That will work, but don't forget there is still the problem with the y-values.

philkr
September 7th, 2005, 05:16 AM
OK, one last time! You don't need the 'b'. It was another mistake. Here is how it goes:
Example with screen height 600:

#define SCREEN_HEIGHT 600
POINT p1, p2;
float m, m1;

p1.x = 100; p1.y = 200;
p2.x = 300; p2.y = 150;

// Convert y values for calculating
p1.y = SCREEN_HEIGHT - p1.y; // = 400
p2.y = SCREEN_HEIGHT - p2.y; // = 450

// Calculate gradients
m = (p2.y - p1.y) / (p2.x - p1.x); // = 50 / 200 = 0.25
m1 = -1/m; // = -1/0.25 = -4

// Calculate perpendicular points by 50 pixel cursor movement
p1.x += 50; // = 150
p2.x += 50; // = 350
p1.y += 50 * m1; // = 400 + 50 * (-4) = 400 - 200 = 200
p2.y += 50 * m1; // = 450 + 50 * (-4) = 450 - 200 = 250

// Convert y-values back
p1.y = SCREEN_HEIGHT - p1.y; // = 600 - 200 = 400
p2.y = SCREEN_HEIGHT - p2.y; // = 600 - 250 = 350

The moved line will be given by P1(150, 400) and P2(350, 350).
Take a look at the picture!

phm
September 7th, 2005, 10:31 PM
I started from scratch and found that using float, double and int(losing precious data) leads to different results. The best approach seems to be when working with floats but in certain situations the behaviour is strange(line moving very fast or going to coordinates like 400,210000 :) ).
I saw you're using int for m and m1.
There should be a simple thing I didn't see until now.

Thanks for your help

philkr
September 8th, 2005, 04:37 AM
I saw you're using int for m and m1.
Doh! Another mistake of mine. It must be float or double since it is almost never an integer.