1
A
答えて
1
もし輪郭が閉じている(Zコマンド)、それは次にsum of interior angle sは
SA = 180 * (n - 2)
nがあり、単純な多角形である場合頂点の数。ここで
は3つの頂点、そうSA = 180
(これは、(彼らは「単純ではない」であり)凹ポリゴンのではなく、自己intesectingもののためにも動作します)
0
は、MBOの答えは良いですが、あればありますドットプロダクトを使用できる角度を明示的に計算する必要があります。 2つのベクトルA = (Ax,Ay), B=(Bx,By)
の場合、内積はA.B = Ax*Bx+Ay*By
で与えられます。 Aの長さが|A|=sqrt(Ax*Ax+Ay*Ay)
の場合、ベクトル間の角度はA . B = |A| |B| cos(angle)
の関係になります。だから、角度は
acos(A . B/(|A| |B|)
によって与えられ、あなたの中に要素SVGコードは、明示的な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>
あなたが角度を見つけることができます使用して:
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);
注結果はMBOからそれに179.99999999999997近いです。
凹型ポリゴンでは機能しないため、上記のコードには小さなバグがあります。これは、角度が反射であるかどうかを見つけるために、クロスバージョンの2Dバージョンを使用して修正することができます。ループの最後に:
cross = Ax * By - Ay * Bx;
if(cross > 0)
sum+=angle;
else
sum += Math.PI*2 - angle;
それは面白いです、私は自己交差するものについても考えませんでした。パスが自己交差しているかどうかを確認する簡単な方法はありますか? – clapin
セグメント数が少ない場合は、すべてのセグメントセグメントの交差(2次複雑度)をチェックする方が簡単です。数百および数千の場合、スイープラインアルゴリズム(O(nlogn))を使用する方が良いでしょう。 – MBo
ありがとう、角度を見るだけでなく、多角形が凹凸であるかどうかを調べる簡単な方法を考え出すことができます。あなたは何か提案がありますか? – clapin