The key idea of the solution is that the ratio of the sides stays the same.
In other words,
(p2.y - p1.y) / (p2.x - p1.x)
... which is stored as slob
in your code, should be equal to both:
(p3.y - p2.y) / (p3.x - p2.x) // shoulders
(p3.y - p1.y) / (p3.x - p1.x) // big triangle
Now, your code attempts to calculate the missing value (p3.y
) based on the first of those. There's a lot of reassigning different values to the same variables (which is a bad practice btw), but in the end it boils down to this equation:
p3.y = slob * (p3.x - p2.x) + p2.y
... which is algebraically correct. Now, the checking expression uses 'big triangle' formula, which can be simplified to this:
p3.x * (p2.y - p1.y) = p1.x * (p2.y - p3.y) + p2.x * (p3.y - p1.y)
Your real problem here is that two approaches - the 'solution' one and the 'checker' one - are different in how they use floating-point math. The checking expression substracts and multiplies its operands, but there's never a case of division there.
It's not like that, however, with 'solution' approach. In the given example, slob
is 6 / 9
- which means it can be stored only with a certain level of precision in JavaScript.
Now, sometimes you get lucky - and the stored value's precision is enough. But sometimes it's snake eyes, like in this infamous example:
0.3 === 0.2 + 0.1 // false
... and you actually get slightly incorrect result stored in p3.y, which is enough to tip the scales of checker equation.