I'm struggling with a problem I thought should be easy to solve:
I'm given two points x1, x2 and a width value. How can I calculate two other points parallel to x1 and x2 so that it forms a rectangle?
I tried answers from here 1 and here 2. Though both solutions are off.
As background: This is about projecting an image into real world coordinates. Therefore I need to find the parallel line to the line I'm provided with, so that the points of both lines create a rectangle. I do not want to apply a rotation on my own.
Here is a drawing that shows what I want to achieve:
In the example you see x1, x2 and the width I'm provided with. And I'm looking for x3 and x4 so that the points form a rectangle.
I'm looking for a C++ implementation if possible.
1 https://gamedev.stackexchange.com/questions/86755/how-to-calculate-corner-positions-marks-of-a-rotated-tilted-rectangle
2 Calculating vertices of a rotated rectangle
Here is the code I've implemented. As you can see I'm using top right and top left coordinates that I'm provided with. But I'd rather find a line parallel to the provided points instead:
double distance = 77.5;//[self normalizedDistanceWithCRS:crs p1:topLeft p2:topRight];
// calculate the rotated coordinates for bottom right and bottom left with provided height
double angle = atan2(sinuTL.y - sinuTR.y, sinuTL.x - sinuTR.x); // * 180 / M_PI
double x = distance;
double y = height;
double xBRTrans = x*cos(angle) - y*sin(angle);
xBRTrans = sinuTL.x - xBRTrans;
double yBRTrans = x*sin(angle) + y*cos(angle);
yBRTrans = sinuTL.y - yBRTrans;
x = 0;
y = height;
double xBLTrans = x*cos(angle) - y*sin(angle);
xBLTrans += sinuTL.x;
double yBLTrans = x*sin(angle) + y*cos(angle);
yBLTrans = sinuTL.y - yBLTrans;
** Update **
I've adapted the code from the solution provided below, The result is still not what I expect. The two points on the left are given, the two points on the right are calculated. You can see that there is an offset (the points should be at the corner of the building. Also ignore the blue point in the middle - it's meaningless to this question):
The code:
double height = 57;
// get coords from provided input
double x1x=629434.24373957072, x1y=5476196.7595944777, x2x=629443.08914538298, x2y=5476120.1852802411;
// x2x3 = Vector from point x2 to point x3, assume x value as 1
double x2x3x = 1;
// calculate y-value, using the fact that dot-product of orthogonal vectors is 0
double x2x3y = x2x*x2x3x / (-1 * x2y);
// calculate length of vector x2x3
double length_e_vec_x2_x3 = sqrt(pow(x2x3x,2) + pow(x2x3y,2));
// stretch vector to provided witdh
x2x3x = x2x3x*height / length_e_vec_x2_x3;
x2x3y = x2x3y*height / length_e_vec_x2_x3;
// since x2x3 and x1x4 are equal, simple addition remains
double x3x, x3y, x4x, x4y;
x3x = x2x + x2x3x;
x3y = x2y + x2x3y;
x4x = x1x + x2x3x;
x4y = x1y + x2x3y;
UPDATE
Actually, all answers and also my own code work as expected. I was unfortunately blindfolded and didn't notice the issue was due to an inappropriate geo projection used for this area. So the coordinates come from WGS84 long/lat, and before the calculation is done get converted into a sinusoidal projection and later back into WGS84. The sinusoidal projection preserves the area (equal area projection) - but distorts shapes within an area. And you cannot just add some meters, and later convert back. I should have realized this earlier and was looking at the wrong place.
I'll choose the most elaborate answer as "winner". Though after testing I can say that all provided solutions actually work.