Skip to main content
TySprice
Known Participant
December 6, 2023
Question

Finding PathItem Intersection Points

  • December 6, 2023
  • 2 replies
  • 923 views

Is there any (relatively) simple method of finding the point or points at which two PathItems intersect? If not, does anyone know of code that is already in existence to determine intersections using the anchors + (right + left  Direction) properties of PathPoints?

This topic has been closed for replies.

2 replies

Sergey Osokin
Inspiring
December 7, 2023

If you are working with simple paths, you can implement the Live Paint trick in a script. After Live Paint > Expand, a point is created at the intersection. We can compare the original array of points and the new array to find the coordinates of the new point. I find this trick fun, but it may not work in some cases.

 

Because Live Paint > Expand shifts the path points slightly, the calculated coordinates of the intersection points are not quite accurate. If you need maximum coordinate accuracy.

 

 

function main() {
  if (selection.length !== 2 || selection.typename === 'TextRange') return;
  var path1 = selection[0];
  var path2 = selection[1];
  if (path1.typename !== 'PathItem' || path2.typename !== 'PathItem' ) return;

  path1.duplicate();
  path1.selected = false;

  path2.duplicate();
  path2.selected = false;

  app.executeMenuCommand('group');
  app.executeMenuCommand('Make Planet X');
  selection[0].translate(0, 0);
  app.executeMenuCommand('Expand Planet X');
  try {
    app.executeMenuCommand('ungroup');
    app.executeMenuCommand('ungroup');
  } catch (e) {}

  var diff = findDiffPoints(path2.pathPoints, selection[1].pathPoints);
  alert('Intersection points:\n' + diff.join('\n'));

  for (var i = selection.length - 1; i >= 0; i--) {
    selection[i].remove();
  }
}

function findDiffPoints(points1, points2) {
  var diff = [];
  for (var i = 0; i < points2.length; i++) {
    var found = false;
    for (var j = 0; j < points1.length; j++) {
      if (matchNum(points2[i].anchor[0], points1[j].anchor[0], 0.1) && 
      matchNum(points2[i].anchor[1], points1[j].anchor[1], 0.1)) {
        found = true;
        break;
      }
    }
    if (!found) diff.push([points2[i].anchor[0].toFixed(3), points2[i].anchor[1].toFixed(3)]);
  }
  return diff;
}

function matchNum(num1, num2, tolerance) {
  var diff = Math.abs(num1 - num2);
  return diff <= tolerance;
}

main();

 

 

m1b
Community Expert
Community Expert
December 8, 2023

Cool idea!

Sergey Osokin
Inspiring
December 8, 2023

Thanks, Mark. Despite the coordinate shift when recalculating Bezier curves with Adobe Illustrator. However, Pathfinder also shifts the points. Also, after Live Paint > Expand, the path may split into several segments. Nevertheless, I used this trick when I wrote my DivideBottomPath script.

 

femkeblanco
Legend
December 6, 2023

I have not seen a ready-made script.  There's a well known algorithm out there to find the intersection of two cubic Bezier curvese (the Bezier subdivision algorithm), but it is not simple, and it will take some work to write it into a script.   

TySprice
TySpriceAuthor
Known Participant
December 7, 2023

Aye, I really appreciate the guidance. Looks like I may have some fun math the attempt to figure out. Will definitely look into re-creating this algorithm in Extendscript and see what I can come up with. Was really hoping someone had already figured it out haha.