Reputation: 109
So I have the following problem that is puzzling me and I can't quite figure out how to do it:
I have two vectors that intersect at one point. The vectors could come in from all kind of different angles like the following two images:
The intersection point is also known, its calculated using the cross product and I got the math behind it from this. Both the start and the end points of the vectors are known aswell.
Now I have a certain line with length X, and I would like to know where between these two vectors this line fits exactly. And then know the coordiates of those points from the vectors. I think this image describes it better:
Ofcourse there are many different ways a line with length X can fit between two vectors, for example the following two images shows different positions of line X between the Vectors A and B, where the line is the same length but the position and angle is different:
If it's possible, I would like that difference in position is determened by the length of the vectors. So if Vector B is five times as long as Vector A, the distance between S and where the line touches Vector B should be 5 times as long as the distance between S and where the line touches Vector A. Like on the above right picture where the distance between S and where the line touches Vector B is far bigger than the distance between S and where the line touches Vector A.
What would be the best way to find out the position of this line? So where on vector A the line starts and where on Vector B it ends? I want to implement this in C++, however calculating the distance between every point on both Vectors and checking if thats equals X seems very intensive and impossible with floats.
Edit: Solution found. Below I'll give a small example.
What you want to do is make up numbers for the length of vector A and B. What I discovered using this site, is that wether you fill in 4 and 8 for sides A and B, or 8 and 16 or anything else having the 1:2 ratio, angles a was the same in all scenarios and so was angle b. So to calculate angles a and b just use for example 5 and 10. What you want to do first(or atleast this is how I did it) is to calculate side C using angle c and side A and B using the following formula:
sqrt(sideA * sideA + sideB * sideB - 2 * sideA * sideB * cos(degreesToRadian(angleC)));
. Note that this is not the same side C and the one given, but just one used to calculate the angles.
After that you can calculate angle a using the following formula:
radianToDegrees(acos((sideB * sideB + sideC * sideC - sideA * sideA) / (2 * sideB * sideC)))
Now that you've found angle a you will have all angles in the triangle. Because you already know angle c, you just calculated a and b = 180 - a - c. The last thing to do is calculate side A and side B using angle c, angle a and the given side C using the following formula:
sideB * sin(degreesToRadian(angleA)) / sin(degreesToRadian(angleB))
When you put it all together in one function that takes in as parameters: (float angleC, float ratioB, float sideC). In our case that is (90, 0.5, 30). Then the calculations are done as following:
float fakeSideA = 10;
float fakeSideB = fakeSideA * ratioB;
float fakeC = sqrt(fakeSideA * fakeSideA + fakeSideB * fakeSideB - 2 * fakeSideA * fakeSideB * cos(degreesToRadian(angleC)));
float angleA = radianToDegrees(acos((fakeSideB * fakeSideB + fakeC * fakeC - fakeSideA * fakeSideA) / (2 * fakeSideB * fakeC)));
float sideA = sideC * sin(degreesToRadian(angleA)) / sin(degreesToRadian(angleC));
std::cout << "SideA: " << sideA << ", AngleA: " << angleA << ", SideC: " << sideC << ", AngleC: " << angleC << std::endl;`
Output should look like: SideA: 26.8328, AngleA: 63.435, SideC: 30, AngleC: 90
. Which is correct. Knowing sideA is the length between S and where the line with length X touches vector A, you can calculate the coordinates for that.
Upvotes: 3
Views: 1478
Reputation: 80327
Let's given segment A, segment B, intersection point S
Find normalized direction vectors of A and B (probably you have already found them when calculated intersection)
dA = (A1.X - A0.X, A1.Y - A0.Y) / Length(A)
dB = (B1.X - B0.X, B1.Y - B0.Y) / Length(B)
and ratio kBA
kBA = Length(B) / Length(A)
End of new segment lying on the B should be kBA times more far from S
EA = S - t * dA
EB = S - t * kBA * dB
Now write equation for length of EA-EB segment,
LenX^2 = (EA.X - EB.X)^2 + (EA.Y - EB.Y)^2
solve it for unknown parameter t, and find points EA and EB (if solutions exist, and they do exist in range of A and B segments)
Denom = (kBA * dB.x - dA.x)^2 + (kBA * dB.y - dA.y)^2
if Denom = 0 then segments are parallel and there is no solution
else
t = +/- sqrt(Len^2 / Denom)
finally
EA.X = S.X - t * dA.X
and so on...
Upvotes: 1
Reputation: 409
You can use the law of cosines.
Here is an illustration of applying this to your problem.
What you should then do is note that the ratio of the magnitude of vector A to vector B allows you to convert from a to b in the picture. From there, C is known, and A = 180 degrees - C - B.
You have six variables, a b c A B C, two constraints (A = 180 - C - B and a = ratio*b), and a constant in the form of C.
You can now select values for two of the three of either a or b, A or B, or c. Use the law of sines to equate this variable to its respective partner. Doing so will leave you with one unknown, which you can use the respective formula on the wolfram page to solve for (or just derive it yourself from one of the formulas on the page).
Edit: Also note that you will need to convert / map the angles you find from these formulas to your original orientation / coordinate system.
Upvotes: 2