如何使用Paper.js计算闭合多边形路径的内角?

时间:2018-11-21 07:37:36

标签: javascript 2d paperjs

将封闭的填充多边形定义为一组点,问题是如何获取构成该多边形的每2条连接线段之间的内角列表。

1 个答案:

答案 0 :(得分:1)

Paper.js允许通过调用getDirectedAngle来获得2个矢量之间的角度(请参见Point类)。这样我们可以获得所有线段之间的角度,只是我们仍然需要一种方法来确定哪个角度值是内部的。

花了一些时间后,我使用这种方法解决了任务。

首先,我计算2个连接段A和B之间的夹角。接下来,我从段A和B相交的连接点C开始评估A和B的中值矢量M。最后,我测试位于A和B之间的中位数的点是在多边形的内部还是在多边形的外部,并据此确定该角度是内部还是外部。

解决方案在下面。

function checkPolygonAngle(path) {
  if (path.curves.length<=1) {
    return;
  } 

  const angleText = function(point, angle) {
    const text = new paper.PointText(point);
    text.justification = 'center';
    text.fillColor = 'black';
    text.content = ""+(Math.round(angle*100)/100);
    return text;
  }
  for (let i=1;i<=path.curves.length;i++) {
    console.log(i);
    const curve1 = path.curves[i-1];
    const curve2 = i==path.curves.length ? path.curves[0] : path.curves[i];
    const v1 = curve1.segment1.point.subtract(curve1.segment2.point);
    const v2 = curve2.segment2.point.subtract(curve2.segment1.point);
    const point = curve1.segment2.point;
    (new paper.Path.Circle(point,3)).fillColor='red';

    const angle = v1.getDirectedAngle(v2);

    const medianAngle = angle/2;
    const medianPoint = curve1.segment1.point.rotate(medianAngle, point);
    const medianVector = medianPoint.subtract(point);
    medianVector.length=30;

    const pointOnMedian = point.add(medianVector);
    (new paper.Path.Line(point,pointOnMedian)).strokeColor='green';
    let insideAngle = null;
    if (path.contains(pointOnMedian)) {
      insideAngle = Math.abs(angle);
      (new paper.Path.Circle(pointOnMedian,3)).fillColor='magenta';
      angleText(pointOnMedian, insideAngle);
    }

    const oppositeMedianVector = medianVector.multiply(-1);
    const pointOnOppositeMedian = point.add(oppositeMedianVector);
    (new paper.Path.Line(point,pointOnOppositeMedian)).strokeColor='blue';
    if (path.contains(pointOnOppositeMedian)) {
      insideAngle = (360 - Math.abs(angle));
      (new paper.Path.Circle(pointOnOppositeMedian,3)).fillColor='magenta';
      angleText(pointOnOppositeMedian, insideAngle);
    }

    console.log(i+":", v1, v2, 'angle: ', insideAngle);
  }
}

Sample of polygon with internal angles