Reputation: 1195
Ok so I need to figure out in JavaScript how to plot a third point on a triangle. See diagram below.
A and B will be randomized points (may be positive or negative depending on where they fall relative to the 0,0 origin.)
thus A and B are known points (x and y).
I already figured out how to plot C based on A and B.
The distance between C and D I want control over. for example I want to say "The distance between C and D is now 20px... where is D?"
So I guess for example purposes we can say that the distance between C&D will be 20px. That means I have CD and CB, but not DB. I also know C(x,y) and B(x,y).
I need to find D now... I'm not a math mind so please explain it to me like I'm 5. I've googled it multiple times, attempted to use multiple examples, and I'm still lost... For example: I saw some equations with phi mentioned.. what is phi? How do I use phi in JavaScript terms, etc...
summary:
A(x,y) is known (randomized)
B(x,y) is known (randomized)
C(x,y) is known (midpoint of AB)
CB is known (using distance formula)
CD = 20 pixels (or whatever I set it to).
DB = ???
D(x,y) = ???
Here's what I have so far, but it's probably wrong..
var Aeh = {x:50, y:75};
var Bee = {x:300, y:175};
var Cee = {x:0, y:0};
var Dee = {x:0, y:0};
window.onload = function(){
refreshPoints();
solveForC();
}
function refreshPoints(){
TweenLite.set("#pointA", {x:Aeh.x, y:Aeh.y});
TweenLite.set("#pointB", {x:Bee.x, y:Bee.y});
TweenLite.set("#pointC", {x:Cee.x, y:Cee.y});
TweenLite.set("#pointD", {x:Dee.x, y:Dee.y});
}
function solveForC() {
Cee.x = (Bee.x + Aeh.x)/2;
Cee.y = (Bee.y + Aeh.y)/2;
refreshPoints();
solveForD();
}
function solveForD() {
// Dee.x = AB * Cos(Φ) + x_1
// Dee.y = AB * Sin(Φ) + y_1
Dee.x = (Cee.x+Bee.x/2) * Math.cos((1 + Math.sqrt(5)) / 2) + Cee.x;
Dee.y = (Cee.y+Bee.y/2) * Math.sin((1 + Math.sqrt(5)) / 2) + Cee.y;
refreshPoints();
}
Upvotes: 3
Views: 2316
Reputation: 54119
Function finds the point dist
from the midpoint of the line A
, B
.
D
is left of the line AB
if left = 1
(default) else D
is right of the line if left = -1
function findD(A, B, dist, left = 1){ // if left = 1 the D is left of the line AB
const nx = B.x - A.x;
const ny = B.y - A.y;
dist /= Math.sqrt(nx * nx + ny * ny) * left;
return {
x : A.x + nx / 2 - ny * dist,
y : A.y + ny / 2 + nx * dist
}
}
You may be tempted to replace the Math.sqrt(nx * nx + ny * ny)
with Math.hypot(nx,ny)
and save 2 multiplications and an addition. But hypot
is agonizingly slow. With the function using sqrt
doing 10million a second when I use hypot
that drops down to 2Million. Also timed the other answer (optimised to be fair) and that peaked at 3.4Million solutions a second.
For javascript using atan2
and sin
and cos
is not that much of an issue as the 64bit double precision float make the error introduced by these functions insignificant, in the range ±1e-14 * length of longest side, but the error can be reduced (a little) if you avoid these functions
Upvotes: 0
Reputation: 3819
You have A, B and C (the midpoint), you know the distance from C to D is set (say at 20), and the line from C to D is at right angles to the line from A to B. You can find two solutions for D using this. The simplest way to understand is to find the angle of the line from A to B, and use that help calculate D.
var angleAB = Math.atan2(B.y - A.y, B.x - A.x);
// to get the angle of the line from C to D, add 90 degrees
// in radians, that is Math.PI / 2
var angleCD = angleAB + Math.PI / 2;
// now you can calculate one of D's solutions
// the 20 represents your distance from C to D, and can be changed if desired.
DeeOne.x = C.x + 20 * Math.cos(angleCD);
DeeOne.y = C.y + 20 * Math.sin(angleCD);
// a second solution can be found by going in the other direction from C
DeeTwo.x = C.x - 20 * Math.cos(angleCD);
DeeTwo.y = C.x - 20 * Math.sin(angleCD);
There might be ways to cut out some of this calculation if all you need is a certain distance (etc) from the diagram. Hope this helps.
Upvotes: 2