2012-03-08 16 views
32

Chcę uzyskać proste rozwiązanie do obliczania kąta linii (jak wskaźnik zegara).Jak obliczyć kąt z punktów?

mam 2 punkty:

cX, cY - the center of the line. 
eX, eY - the end of the line. 

The result is angle (0 <= a < 360). 

Która funkcja jest w stanie zapewnić tę wartość?

+0

Trzeba co najmniej trzy punkty, aby obliczyć kąt. Który z was jest trzeci? Oś X lub oś Y? – Sirko

+2

Zakładając oś x –

+0

2 wymiarowa linia. – durumdara

Odpowiedz

72

Chcesz tangens:

dy = ey - cy 
dx = ex - cx 
theta = arctan(dy/dx) 
theta *= 180/pi // rads to degs 

ERM, trzeba pamiętać, że powyższe nie jest oczywiście kompilacji kodu Javascript. Będziesz musiał przejrzeć dokumentację funkcji arctangent.

Edit: Korzystanie Math.atan2(y,x) będzie obsługiwać wszystkich szczególnych przypadkach oraz dodatkową logikę dla Ciebie:

function angle(cx, cy, ex, ey) { 
    var dy = ey - cy; 
    var dx = ex - cx; 
    var theta = Math.atan2(dy, dx); // range (-PI, PI] 
    theta *= 180/Math.PI; // rads to degs, range (-180, 180] 
    //if (theta < 0) theta = 360 + theta; // range [0, 360) 
    return theta; 
} 
+5

Człowieku, kochałem trygonometrykę. – Purag

+5

Należy pamiętać, że aby uniknąć dzielenia przez 0, należy najpierw sprawdzić, czy "dx == 0"; jeśli tak, to wróć do 90 stopni, jeśli 'dy> 0' i 270 stopni, jeśli' dy <0'. –

+0

@EtiennePerot: Zapamiętałem inną użyteczną funkcję i zaktualizowałem moją odpowiedź, by użyć zamiast tego. –

8

Runnable wersja Christian's answer.

function angle(cx, cy, ex, ey) { 
 
    var dy = ey - cy; 
 
    var dx = ex - cx; 
 
    var theta = Math.atan2(dy, dx); // range (-PI, PI] 
 
    theta *= 180/Math.PI; // rads to degs, range (-180, 180] 
 
    return theta; 
 
} 
 
function angle360(cx, cy, ex, ey) { 
 
    var theta = angle(cx, cy, ex, ey); // range (-180, 180] 
 
    if (theta < 0) theta = 360 + theta; // range [0, 360) 
 
    return theta; 
 
} 
 

 
show("right", 0, 0, 1, 0); 
 
show("top right", 0, 0, 1, 1); 
 
show("top", 0, 0, 0, 1); 
 
show("top left", 0, 0, -1, 1); 
 
show("left", 0, 0, -1, 0); 
 
show("bottom left", 0, 0, -1, -1); 
 
show("bottom", 0, 0, 0, -1); 
 
show("bottom right", 0, 0, 1, -1); 
 

 
// IGNORE BELOW HERE (all presentational stuff)
table { 
 
    border-collapse: collapse; 
 
} 
 
table, th, td { 
 
    border: 1px solid black; 
 
    padding: 2px 4px; 
 
} 
 
tr > td:not(:first-child) { 
 
    text-align: center; 
 
} 
 
tfoot { 
 
    font-style: italic; 
 
}
<table> 
 
    <thead> 
 
    <tr><th>Direction*</th><th>Start</th><th>End</th><th>Angle</th><th>Angle 360</th></tr> 
 
    </thead> 
 
    <tfoot> 
 
    <tr><td colspan="5">* Cartesian coordinate system<br>positive x pointing right, and positive y pointing up.</td> 
 
    </tfoot> 
 
    <tbody id="angles"> 
 
    </tbody> 
 
</table> 
 
<script> 
 
function show(label, cx, cy, ex, ey) { 
 
    var row = "<tr>"; 
 
    row += "<td>" + label + "</td>"; 
 
    row += "<td>" + [cx, cy] + "</td>"; 
 
    row += "<td>" + [ex, ey] + "</td>"; 
 
    row += "<td>" + angle(cx, cy, ex, ey) + "</td>"; 
 
    row += "<td>" + angle360(cx, cy, ex, ey) + "</td>"; 
 
    row += "</tr>"; 
 
    document.getElementById("angles").innerHTML += row; 
 
} 
 
</script>

0

Jeden problem z uzyskanie kąta między dwoma punktami lub dowolnym kątem jest odniesienie użyć.

W matematyce używamy koła trygonometrycznego z punktem początkowym po prawej stronie okręgu (punkt w x = promień, y = 0) i liczymy kąt przeciwnie do ruchu wskazówek zegara od 0 do 2PI.

W geografii pochodzenie jest północ na 0 stopni i idziemy zgodnie z ruchem wskazówek zegara od do 360 stopni.

Poniższy kod (C#) pobiera kąt w radianach następnie przekształca się pod kątem geograficznym:

public double GetAngle() 
    { 
     var a = Math.Atan2(YEnd - YStart, XEnd - XStart); 
     if (a < 0) a += 2*Math.PI; //angle is now in radians 

     a -= (Math.PI/2); //shift by 90deg 
     //restore value in range 0-2pi instead of -pi/2-3pi/2 
     if (a < 0) a += 2*Math.PI; 
     if (a < 0) a += 2*Math.PI; 
     a = Math.Abs((Math.PI*2) - a); //invert rotation 
     a = a*180/Math.PI; //convert to deg 

     return a; 
    } 
0

Jeśli używasz płótno, zauważysz (jeśli jeszcze go nie masz), które płótno używa obrotu w prawo (MDN) i y oś jest odwrócona. Aby uzyskać spójne wyniki, musisz zmodyfikować swoją funkcję angle.

Od czasu do czasu muszę napisać tę funkcję i za każdym razem muszę ją sprawdzić, ponieważ nigdy nie dochodzę do sedna obliczeń.

Podczas gdy sugerowane rozwiązania działają, nie uwzględniają układu współrzędnych obszaru roboczego. Zbadać następujące demo:

Calculate angle from points - JSFiddle

function angle(originX, originY, targetX, targetY) { 
    var dx = originX - targetX; 
    var dy = originY - targetY; 

    // var theta = Math.atan2(dy, dx); // [0, Ⲡ] then [-Ⲡ, 0]; clockwise; 0° = west 
    // theta *= 180/Math.PI;   // [0, 180] then [-180, 0]; clockwise; 0° = west 
    // if (theta < 0) theta += 360;  // [0, 360]; clockwise; 0° = west 

    // var theta = Math.atan2(-dy, dx); // [0, Ⲡ] then [-Ⲡ, 0]; anticlockwise; 0° = west 
    // theta *= 180/Math.PI;   // [0, 180] then [-180, 0]; anticlockwise; 0° = west 
    // if (theta < 0) theta += 360;  // [0, 360]; anticlockwise; 0° = west 

    // var theta = Math.atan2(dy, -dx); // [0, Ⲡ] then [-Ⲡ, 0]; anticlockwise; 0° = east 
    // theta *= 180/Math.PI;   // [0, 180] then [-180, 0]; anticlockwise; 0° = east 
    // if (theta < 0) theta += 360;  // [0, 360]; anticlockwise; 0° = east 

    var theta = Math.atan2(-dy, -dx); // [0, Ⲡ] then [-Ⲡ, 0]; clockwise; 0° = east 
    theta *= 180/Math.PI;   // [0, 180] then [-180, 0]; clockwise; 0° = east 
    if (theta < 0) theta += 360;  // [0, 360]; clockwise; 0° = east 

    return theta; 
} 
Powiązane problemy