2016-04-19 8 views

答えて

1

もし輪郭が閉じている(Zコマンド)、それは次にsum of interior angle sは

SA = 180 * (n - 2) 

nがあり、単純な多角形である場合頂点の数。ここで

は3つの頂点、そうSA = 180

(これは、(彼らは「単純ではない」であり)凹ポリゴンのではなく、自己intesectingもののためにも動作します)

+0

それは面白いです、私は自己交差するものについても考えませんでした。パスが自己交差しているかどうかを確認する簡単な方法はありますか? – clapin

+0

セグメント数が少ない場合は、すべてのセグメントセグメントの交差(2次複雑度)をチェックする方が簡単です。数百および数千の場合、スイープラインアルゴリズム(O(nlogn))を使用する方が良いでしょう。 – MBo

+0

ありがとう、角度を見るだけでなく、多角形が凹凸であるかどうかを調べる簡単な方法を考え出すことができます。あなたは何か提案がありますか? – clapin

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;