Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Math 如何计算SVG路径的内角之和?_Math_Svg - Fatal编程技术网

Math 如何计算SVG路径的内角之和?

Math 如何计算SVG路径的内角之和?,math,svg,Math,Svg,例如,下面这样的路径: <path d="M 35 50 L 35 35 L 90 90 z" fill="goldenrod"/> 如果轮廓是闭合的(z命令),并且是简单多边形,则s是 其中n是顶点数 这里有3个顶点,因此SA=180 (它也适用于凹多边形,但不适用于自相交多边形(它们“不简单”)MBo的答案很好,但如果您想显式计算角度,可以使用点积。对于两个向量A=(Ax,Ay),B=(Bx,By)点积由A.B=Ax*Bx+Ay*By给出。如果A的长度是| A |=sqrt(

例如,下面这样的路径:

<path d="M 35 50 L 35 35 L 90 90 z" fill="goldenrod"/>

如果轮廓是闭合的(z命令),并且是简单多边形,则s是

其中n是顶点数

这里有3个顶点,因此
SA=180


(它也适用于凹多边形,但不适用于自相交多边形(它们“不简单”)

MBo的答案很好,但如果您想显式计算角度,可以使用点积。对于两个向量
A=(Ax,Ay),B=(Bx,By)
点积由
A.B=Ax*Bx+Ay*By
给出。如果A的长度是
| A |=sqrt(Ax*Ax+Ay*Ay)
,则向量之间的角度具有关系
A。B=| A | B | cos(角度)
。所以这个角度是由

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>

这很有趣,我甚至没有想到自交的。是否有一种简单的方法来检查路径是否自交?对于少量线段(几十条),检查所有线段相交(二次复杂度)更简单,对于成百上千条线段,最好使用扫描线算法(O(nlogn))谢谢,除了看角度之外,我还试图找到一种更简单的方法来检查多边形是否凹/凸。您有什么建议吗?是的,您可以按顺序计算相邻边的叉积,并检查它们的符号。对于凸多边形,所有叉积符号都相同(或正,或负,取决于行走方向)
<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);
   cross = Ax * By - Ay * Bx;
   if(cross > 0)
       sum+=angle;
   else
     sum += Math.PI*2 - angle;