User is changing one vertex of first line (current line) and the second line instantly should become parallel to first line. To reach this I'm trying to find angle between two vectors of these lines using formula:
vec1.x =(x-x2), vec1.y =(y-y2); // coordinates of first vector (x,y) - user-editable point
vec2.x =(x3-x4), vec2.y =(y3-y4); // coordinates of second vector
double angle = acos(
( vec1.x * vec2.x + vec1.y * vec2.y )
/
sqrt( ( SQR(vec1.x) + SQR(vec1.y) ) * ( SQR(vec2.x) + SQR(vec2.y) ) )
);
when
x > x2
formula givesangle > 90°
when
x < x2
formula givesangle < 90°
and then rotate second line by angle
point xAxis = point{cos(angle),sin(angle)};
point yAxis = point{-sin(angle),cos(angle)};
point origin = point{x3,y3};
point p = point{x4-origin.x, y4-origin.y};
x4 = origin.x + p.x * xAxis.x + p.y * yAxis.x;
y4 = origin.y + p.x * xAxis.y + p.y * yAxis.y;
when I'm rotating line counterclockwise all is fine, second line makes parallel to first one,
but when I'm rotating line clockwise second line starts a freak show
I'm guessing that in certain conditions instead of rotating second line by angle
I should rotate it by -angle
cos(a) == cos(-a)
, so acos(cos(a))
might give you either a
or -a
. Both are correct.
If you want to get the angle of a vector, use atan2(y,x)
, which covers the whole circle. If you want to use your cosine solution, you have to distinguish between the positive and negative of the angle yourself and make sure the result is in the right quadrant.
But your problem is more easily solved like this:
len1 = sqrt((x2-x)*(x2-x) + (y2-y)*(y2-y));
len2 = sqrt((x4-x3)*(x4-x3) + (y4-y3)*(y4-y3));
x4 = x3 + (x2-x)*len2/len1;
y4 = y3 + (y2-y)*len2/len1;
You just make new line in the direction of the first one, with the length of the second one. Check for len1==0.0
, since the direction is undefined in that case.
Note also that, no matter how you do this, you will be accumulating errors as the user drags the point. Each time you change line2, the length will change a tiny bit, and then you're going to use this as the basis for the next one. The errors are small and you probably won't notice, but you should really remember len2
at the beginning and use that value for all future operations.