Cmaxster
Cmaxster

Reputation: 1195

Finding 3rd point in Triangle using JavaScript

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();
    }

diagram

Upvotes: 3

Views: 2316

Answers (2)

Blindman67
Blindman67

Reputation: 54119

A slightly quicker and more accurate alternative solution.

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

arbuthnott
arbuthnott

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

Related Questions