Reputation: 724
Having a closed filled polygon defined as a set of points, question is how to get a list of internal angles between each 2 connecting segment lines that make up this polygon.
Upvotes: 0
Views: 580
Reputation: 724
Paper.js allows to get angle between 2 vectors by calling getDirectedAngle (See class Point). So we can get angles between all segments, just we still need a way to decide which angle value is internal.
After spending some time i solved the task using this method.
First, i calculate angle between 2 connecting segments A and B. Next, i evaluate median vector M for A and B starting from the connecting point C where segments A and B meet. Finally i test whether point that lies on median between A and B is inside of polygon or outside of it and based on that i decide if this angle is internal or external.
Solution is below.
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);
}
}
Upvotes: 1