Suppose we have an array of points that can be used to draw an SVG/vector path.
const points = [[1,1], [3,4], .....];
I want the path or coordinates of the outer boundary of this path as shown below.
There is a way to find union of overlapping polygons but in my case I have a single overlapping path and not multiple overlapping polygons.
CodePudding user response:
Paper.js Boolean operations might be helpful.
The unite()
method can merge single or multiple shapes to remove any overlap:
paper.install(window);
const svg = document.querySelector("svg");
const canvas = document.querySelector("#canvasPaper");
const polygonPoints = [
[38.2, 26.3],
[24.4, 25.7],
[18.4, 41],
[23.6, 61.9],
[40, 64.4],
[50.1, 50.5],
[39.1, 38.8],
[30.2, 45.1],
[49.3, 61.5],
[59.2, 60.9],
[71.3, 54.7],
[74.2, 38.5],
[68.7, 27.8],
[60.4, 20],
[46.3, 25.5],
[45.8, 38.3],
[61.2, 41.6],
[72.3, 28.4],
[69.9, 20],
[62.1, 14.3],
[43.6, 14.3],
[38.2, 26.3]
];
// create an render initial polygon
const mergedPolygon = document.createElementNS("http://www.w3.org/2000/svg", "path");
mergedPolygon.setAttribute("fill", 'none');
mergedPolygon.setAttribute("stroke", '#000');
svg.appendChild(mergedPolygon);
// convert polygon points to path commands
let polygonD = polygonToPath(polygonPoints);
mergedPolygon.setAttribute("d", polygonD);
function unite() {
paper.setup("canvasPaper");
let path = new Path(polygonD);
// merge/unite path
let united = path.unite();
// get svg d
let unitedData = united
.exportSVG({
precision: 3
})
.getAttribute("d");
united.strokeColor = "black";
united.scale(2, new Point(0, 0));
//update svg
mergedPolygon.setAttribute("d", unitedData);
}
//convert polygon point array to path d
function polygonToPath(points) {
let d = `M ${points[0][0]} ${points[0][1]}`;
for (let i = 1; i < points.length; i ) {
d = `L ${points[i][0]} ${points[i][1]}`;
}
return d "z";
}
canvas,
svg {
display: inline-block;
border: 1px solid #ccc;
width:400px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.12.0/paper-full.min.js"></script>
<p>
<button type="button" onclick="unite()">Unite Path </button>
</p>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 100">
</svg>
<canvas id="canvasPaper" width="400" height="200"></canvas>
Conversion steps
- we convert the polygon point array to path commands, using a helper function
polygonToPath(points)
. (See also: Convert SVG polygon to path) - we create a paper path node by
new Path(polygonD)
- overlaps are removed by
path.unite()
exportSVG()
will return svg commands of the united/merged path