Zum Beispiel wird ein Pfad wie unten:Wie würden Sie die Summe der Innenwinkel von einem SVG-Pfad berechnen?
<path d="M 35 50 L 35 35 L 90 90 z" fill="goldenrod"/>
Zum Beispiel wird ein Pfad wie unten:Wie würden Sie die Summe der Innenwinkel von einem SVG-Pfad berechnen?
<path d="M 35 50 L 35 35 L 90 90 z" fill="goldenrod"/>
Wenn Kontur (z-Befehl) geschlossen, und es ist einfach, polygon, dann sum of interior angle s
SA = 180 * (n - 2)
ist, wobei n die ist Anzahl der Ecken.
Hier gibt es 3 Ecken, so SA = 180
(Es funktioniert auch für konkave Polygone, aber nicht für die Selbst intesecting diejenigen (sie sind ‚nicht einfach‘))
MBO Antwort ist gut, aber wenn Sie möchten explizit die Winkel berechnen, die Sie für das Skalarprodukt verwenden können. Für zwei Vektor A = (Ax,Ay), B=(Bx,By)
ist das Skalarprodukt gegeben durch A.B = Ax*Bx+Ay*By
. Wenn die Länge von A |A|=sqrt(Ax*Ax+Ay*Ay)
ist, hat der Winkel zwischen den Vektoren die Beziehung A . B = |A| |B| cos(angle)
. Also ist der Winkel gegeben durch
acos(A . B/(|A| |B|)
Angenommen, das Element in dir Svg Code hat eine explizite ID.
<svg id="picture" version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="400" height="300">
<path id="poly" d="M 35 50 L 35 35 L 90 90 z" fill="goldenrod"/>
</svg>
können Sie die Winkel finden Verwendung:
poly = document.getElementById("poly"); // get the svg element
// get the parts of the d attribute and split on space.
parts = poly.getAttribute("d").split(/\s+/);
x=[],y=[]; // Arrays to hold x,y coords
j=0;
// loop through parts of svg, extract x,y coords
for(i=0;i<parts.length-1;i+=3) {
x[j]=parts[i+1];
y[j]=parts[i+2];
++j;
}
sum=0; // variable to hold the sum
for(var i=0;i<x.length;++i) { // loop through each vertex
prev = i >0 ? i-1 : x.length-1; // get previous index
next = (i+1) % x.length; // get next index
Ax = x[next] - x[i]; Ay = y[next] - y[i]; // vector A
Bx = x[prev] - x[i]; By = y[prev] - y[i]; // Vector B
dot = Ax * Bx + Ay * By; // dot product
lenA = Math.sqrt(Ax*Ax + Ay*Ay); // Length of A
lenB = Math.sqrt(Bx*Bx + By*By); // Or use Math.hypot
angle = Math.acos(dot/(lenA * lenB)); // find angle using
sum+=angle; // find sum
}
// print the sum (using degrees)
console.log(180 * sum/Math.PI);
Hinweis ist das Ergebnis 179,99999999999997 nahe an dem von MBO.
Es gibt einen kleinen Fehler im obigen Code, da er nicht mit konkaven Polygonen funktioniert. Dies kann mit einer 2D-Version des Kreuzprodukts behoben werden, um herauszufinden, ob der Winkel ein Reflex ist. Am Ende der Schleife hinzufügen:
cross = Ax * By - Ay * Bx;
if(cross > 0)
sum+=angle;
else
sum += Math.PI*2 - angle;
Das ist interessant, ich dachte nicht einmal über sich selbst schneidende. Gibt es eine einfache Möglichkeit zu überprüfen, ob der Pfad sich selbst schneidet? – clapin
Für kleine Anzahl von Segmenten (Dutzende) ist es einfacher, alle Segment-Segment-Kreuzung (quadratische Komplexität) zu überprüfen, für Hunderte und Tausende wäre es besser, Sweep-Line-Algorithmus zu verwenden (O (nlogn)) – MBo
Danke, ich versuche auch um einen einfacheren Weg zu finden, um zu überprüfen, ob ein Polygon konkav/konvex ist, und nur die Winkel zu betrachten. Hast du irgendwelche Vorschläge? – clapin