Как рассчитать внутренние углы замкнутого многоугольника с помощью Paper.js? - PullRequest
0 голосов
/ 21 ноября 2018

Имея замкнутый заполненный многоугольник, определенный как набор точек, вопрос заключается в том, как получить список внутренних углов между каждыми 2 линиями соединительных сегментов, составляющих этот многоугольник.

1 Ответ

0 голосов
/ 21 ноября 2018

Paper.js позволяет получить угол между 2 векторами, вызвав getDirectedAngle (см. Класс Point).Таким образом, мы можем получить углы между всеми сегментами, просто нам по-прежнему нужен способ решить, какое значение угла является внутренним.

Потратив некоторое время, я решил задачу, используя этот метод.

Сначала я вычисляю угол между двумя соединительными сегментами A и B. Затем я оцениваю медианный вектор M для A и B, начиная с точки соединения C, где встречаются сегменты 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

...