SVG intersection of elements with transforms

290 Views Asked by At

The Intersection library from Kevin Lindsey allows to easily compute intersections between several types of svg elements (paths, rectangles, lines...).

However, it does not seem to take into account the transformations applied via transform="translate(x,y) rotate(r)" to any of the objects.

<svg>
    <polygon id="machine" transform="translate(40,25) rotate(45)"... />
    <path id="outer" ... />
</svg>

<script>
var machine = document.getElementById("machine")
var outer = document.getElementById("outer")

var m = new Polygon(machine)
var o = new Path(outer)

Intersection.intersectPathShape(o, m) // incorrect
</script>

Is there a way to take the transformations applied to any element into account while computing intersections?

1

There are 1 best solutions below

0
On

You could try changing the values of to their 'screen' values, extracting the transforms. Below are some examples for polygons and paths(except arcs): Note on paths: Chrome deprecated pathSegList recently and now requires a polyfill, https://github.com/progers/pathseg

//---except arc paths---
function screenPath(path)
{
 var sCTM = path.getCTM()
 var svgRoot = path.ownerSVGElement

 var segList=path.pathSegList
 var segs=segList.numberOfItems
 //---change segObj values
 for(var k=0;k<segs;k++)
 {
  var segObj=segList.getItem(k)

  if(segObj.x && segObj.y )
  {
   var mySVGPoint = svgRoot.createSVGPoint();
   mySVGPoint.x = segObj.x
   mySVGPoint.y = segObj.y
   mySVGPointTrans = mySVGPoint.matrixTransform(sCTM)
   segObj.x=mySVGPointTrans.x
   segObj.y=mySVGPointTrans.y
  }

  if(segObj.x1 && segObj.y1)
  {
   var mySVGPoint1 = svgRoot.createSVGPoint();
   mySVGPoint1.x = segObj.x1
   mySVGPoint1.y = segObj.y1
   mySVGPointTrans1 = mySVGPoint1.matrixTransform(sCTM)
   segObj.x1=mySVGPointTrans1.x
   segObj.y1=mySVGPointTrans1.y
  }
  if(segObj.x2 && segObj.y2)
  {
   var mySVGPoint2 = svgRoot.createSVGPoint();
   mySVGPoint2.x = segObj.x2
   mySVGPoint2.y = segObj.y2
   mySVGPointTrans2 = mySVGPoint2.matrixTransform(sCTM)
   segObj.x2=mySVGPointTrans2.x
   segObj.y2=mySVGPointTrans2.y
  }
 }
 //---force removal of transform--
 path.setAttribute("transform","")
 path.removeAttribute("transform")
}

//---changes all transformed points to screen points---
function screenPolygon(myPoly)
{
 var sCTM = myPoly.getCTM()
 var svgRoot = myPoly.ownerSVGElement

 var pointsList = myPoly.points;
 var n = pointsList.numberOfItems;
 for(var m=0;m<n;m++)
 {
  var mySVGPoint = svgRoot.createSVGPoint();
  mySVGPoint.x = pointsList.getItem(m).x
  mySVGPoint.y = pointsList.getItem(m).y
  mySVGPointTrans = mySVGPoint.matrixTransform(sCTM)
  pointsList.getItem(m).x=mySVGPointTrans.x
  pointsList.getItem(m).y=mySVGPointTrans.y
 }
 //---force removal of transform--
 myPoly.setAttribute("transform","")
 myPoly.removeAttribute("transform")
}