3

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:

Example 1 Example 2

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:

Example 3 Example 4

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:

Example 3 again Example 5

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.

  • Let's say angle c (the angle between vector A and vector B) is 90 degrees.
  • The ratio is 1:2(so B is twice as long as A).
  • And last the side C is 30.

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.

Community
  • 1
  • 1
JohnCake
  • 109
  • 8

2 Answers2

2

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.

Shawn
  • 409
  • 3
  • 12
  • I think I'm missing something here, but I cant seem to narrow it down to one unknown. I now have "b^2 = (ratio * b)^2 + c^2 - 2 * (ratio * b) * c * cos(180 - A - C)". c is line I know the length of, and angle C is calculable, leaving me with the unknowns b and A. Not sure how to go from here. – JohnCake Jul 06 '16 at 00:05
  • You start with: a b c A B C. You know c and C. You now need a b A B. b = a / ratio. B = 180 - C - A. You now need b and A, as you said. Since you have two unknowns for a single formula, this means you have infinite combinations of possible answers. So choose a value for either b or A (I would choose one with some significance, but you can choose a random value) and use that to solve for the final unknown. Basically as you have two unknowns and one formula your system is underdefined, you need to define another variable to solve the system. – Shawn Jul 06 '16 at 01:56
  • I'm sorry but im really not getting it. If I just fill in a random value the final unknown will always be different, 90% of the time its even incalculable so I'm really confused as it shouldn't be different right? – JohnCake Jul 06 '16 at 13:55
  • Could you for example, show me how the values are calculated if the ratio is 2(meaning b is twice as long as a), C is 90 degrees and c is 32? – JohnCake Jul 06 '16 at 14:19
  • We need to find b or A in your example. To do this, I would use the [law of sines](https://www.mathsisfun.com/algebra/trig-sine-law.html) (though I am sure there are other methods). This states that c/sinC = b/sinB = a/sinA. You know c and C. Thus, note that b=2a, and a=sinA *c/sinC. We now only have one unknown to find: the value of A. When we find A, we will have a value for B (being 180-C-A) and a value for a (seen prior) and for b (b=2a). The trick is to acknowledge that you are making a triangle with your constraints. – Shawn Jul 06 '16 at 14:45
  • Excuse my stupidity but I'm still not seeing it. How do we find A? I'm still stuck with two unknowns being a and A in your answer. I've written it down ten times but I just dont seem to get to an answer myself =/. Any chance you could show the entire process and the final values/answers? – JohnCake Jul 06 '16 at 16:11
  • After giving it a rest for a week I looked upon your explaination it with fresh eyes and figured it out, finished result of what I gathered is edited in the main post. Thanks for the help. – JohnCake Jul 13 '16 at 22:11
  • No problem. Sorry didn't mean to ignore, I guess I must have just clicked on the notification once and then forgotten to reply, but it's good to hear you figured it out. – Shawn Jul 14 '16 at 16:10
1

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...
MBo
  • 77,366
  • 5
  • 53
  • 86
  • I think it should be **EB** = **S** - t * kBA * **dB** (not **dA**), with the last equation boiling down to t = sqrt(Len^2 / ((kBA * dB.x - dA.x)^2 + (kBA * dB.y - dA.y)^2)), if I haven't missed some step... – Bob__ Jul 06 '16 at 08:52
  • For dB - yes, copy-past error. For the last equation - yes, all is correct (+- solutions are possible and zero divisor for parallel lines) – MBo Jul 06 '16 at 08:59
  • there are many more unknowns here than t; EA are two numbers (x, y) not one and so for EB; so you need to bring this down to detail otherwise its an unsolvable system – gpasch Jul 07 '16 at 04:08
  • @gpasch You ane not right. `t` is the only unknown. Both EA.X and EA.Y are expressed through known coordinates and t – MBo Jul 07 '16 at 04:11
  • obviously there is some fallacy in your formulation; you are suggesting there are only two positions where the segment fits; that is not true; I sense the fallacy is located around your mixing normalized dA with unnornalized S – gpasch Jul 07 '16 at 04:39
  • Yes, there are only two positions - look at author's last but one paragraph- that is why I've introduced kBA ratio – MBo Jul 07 '16 at 04:49