Home > Software engineering >  Get outer boundary path or coordinates of an overlapping svg/vector path
Get outer boundary path or coordinates of an overlapping svg/vector path

Time:07-10

Suppose we have an array of points that can be used to draw an SVG/vector path.

const points = [[1,1], [3,4], .....];

enter image description here

I want the path or coordinates of the outer boundary of this path as shown below.

enter image description here

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

  1. we convert the polygon point array to path commands, using a helper function polygonToPath(points). (See also: Convert SVG polygon to path)
  2. we create a paper path node by new Path(polygonD)
  3. overlaps are removed by path.unite()
  4. exportSVG() will return svg commands of the united/merged path
  • Related