Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Looking for a way to test if the lines in a path intersect any objects?

Engaged ,
Feb 09, 2011 Feb 09, 2011

What i'd like to do is select an open ended path, and generate an array of all the objects that path intersects.  Here's an image to illustrate:

example.jpg

The green line would be selected.  The script would run and populate an array with pointers to each yellow square the line intersects.  Does anyone have any ideas on how this can be done in javascript?  Or if it is possible at all?  Help is appreacited, thanks!

TOPICS
Scripting
3.2K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Feb 14, 2011 Feb 14, 2011

what?? a new document function?? I'm not kidding CS5 DOM has a new function!!! I know...it is hard to believe. And with it, new doors seem to open, like testing if a path intersects little yellow squares...no math required.

selectObjectsOnActiveArtboard() //

#target Illustrator

/* loops thru all objects to test for intersection with
    a path (path must be top object), start with nothing
    selected. Script assumes, 1 artboard.
*/

var idoc = app.activeDocument;
var yellowSq = idoc.pathItem;
var abRec
...
Translate
Adobe
Advocate ,
Feb 11, 2011 Feb 11, 2011

Sure it's possible. If all of your objects-to-cross are rectangles (as in your image), it's even quite trivial.

(15 minutes later) Oh well, perhaps not "trivial" -- I'd have to check at home whether or not I got a full-fledged rectangle intersection code. This doesn't work -- the "crossObject" function needs a bit more work.

At least it'll give you something to look at.

if (app.selection.length != 1)
alert ("Wot no single path selected?");
else
{
if (!(app.selection[0] instanceof PathItem))
  alert ("Wot no path?");
else
{
  allObjects = [];
  for (i=0; i<app.activeDocument.pageItems.length; i++)
   if (!app.activeDocument.pageItems.selected)
    allObjects.push (app.activeDocument.pageItems);
  thePath = [];
  for (i=0; i<app.selection[0].pathPoints.length; i++)
   thePath.push ([ app.selection[0].pathPoints.anchor[0],app.selection[0].pathPoints.anchor[1] ] );
  
  app.selection[0].selected = false;

  for (i=0; i<thePath.length-1; i++)
  {
   for (j=0; j<allObjects.length; j++)
   {
   // only check if necessary
    if (allObjects.selected == true)
     continue;
    if (crossObject (thePath, thePath[i+1], allObjects))
     allObjects.selected = true;
   }
  }
}
}

// .. to do .. (dis doesn't work)
// (check Liang-Barsky or Cohen-Sutherland viewport clipping)
function crossObject (a, b, obj)
{
var xl = obj.visibleBounds[1];
var xr = obj.visibleBounds[3];
var yt = obj.visibleBounds[0];
var yb = obj.visibleBounds[2];

var x1 = a[0],y1 = a[1];
var x2 = b[0],y2 = b[1];

// if point is inside object, it (obviously) hits
if (x1 > xl && x1 < xr && y1 > yt && y1 < yb)
  return true;
if (x2 > xl && x2 < xr && y2 > yt && y2 < yb)
  return true;

return false;
}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Feb 13, 2011 Feb 13, 2011

In your example none of your selected path's points actually fall within your other shapes bounds what you could do is travel down your path creating imaginary points along that path. Then test if these fall inside the bounds of each of your shapes. This kind of stuff is too complicated math for me. This should give you the general idea of what I mean. You don't need these as path points (just x & y co-ords to test against) but it shows the principle all be it very basic (like my math)…

function activeDoc() {            if (app.documents.length == 0) {                      alert('NO document open?');           return;      } else {                      var docRef = app.activeDocument;                      var docSel = docRef.selection;                      if (docSel.length == 1 && docSel[0].typename == 'PathItem') {                                var pPoints = docSel[0].pathPoints;                                for (var i = 0; i < pPoints.length-1; i++) {                                               var start = pPoints.anchor;                                               var end = pPoints[i+1].anchor;                                               pointsInBetween(start,end,20);                                          }                                if (docSel[0].closed) {                                          var start = pPoints[pPoints.length-1].anchor;                                          var end = pPoints[0].anchor;                                          pointsInBetween(start,end,20);                                     }                           }                 }       } activeDoc(); function pointsInBetween(s,e,t) {            for (var i = 1; i < t; i++) {                 var x = s[0] + ((e[0] - s[0]) / t) * i;                 var y = s[1] + ((e[1] - s[1]) / t) * i;                 var a = app.activeDocument.pathItems.add()                 var b = a.pathPoints.add()                 b.anchor = Array(x,y)           b.leftDirection = b.anchor;           b.rightDirection = b.anchor;           b.pointType = PointType.CORNER;            } }

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 14, 2011 Feb 14, 2011

what?? a new document function?? I'm not kidding CS5 DOM has a new function!!! I know...it is hard to believe. And with it, new doors seem to open, like testing if a path intersects little yellow squares...no math required.

selectObjectsOnActiveArtboard() //

#target Illustrator

/* loops thru all objects to test for intersection with
    a path (path must be top object), start with nothing
    selected. Script assumes, 1 artboard.
*/

var idoc = app.activeDocument;
var yellowSq = idoc.pathItem;
var abRect = idoc.artboards[0].artboardRect;
var tempRect = abRect;
var yellowSqs = [];

for (i=1;i<=idoc.pathItems.length-1;i++)
    {
        yellowSq = idoc.pathItems;
        idoc.artboards[0].artboardRect = yellowSq.visibleBounds;
        idoc.selectObjectsOnActiveArtboard();
       
        if (idoc.pathItems[0].selected)
            {
                //alert ("yes!!");
                yellowSq.fillColor = idoc.swatches["White"].color;
                yellowSqs.push(yellowSq);
            }
        idoc.pathItems[0].selected = false;
        yellowSq.selected = false;
        }
   
    idoc.artboards[0].artboardRect = tempRect;
   
   alert("the green line intersects " + yellowSqs.length + " yellow squares");

yellowSquares.PNG

update: added snapshot

Message was edited by: CarlosCanto

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Feb 17, 2011 Feb 17, 2011

That's brillant!  I actually went with creating "pseudo points" along each section of the line and testing whether that was inside the bounds of the objects, only because I needed to number the objects in the order in which the line intersects them.  I've got the script working and it's running great.  However, it only works with straight lines.  If a curved line is used, the pseudo point get generated in a straight line between the 2 end point of the line.   I need to be able to create those pseudo point along curved lines.  Further more, I need the point to "step" the same distance across the line.  Does anyone have any insights on how to impliment this?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Feb 18, 2011 Feb 18, 2011

some time ago i posted a library for working with beziers here, including intersections.

please use the search (bezier).

at the end of the lib are runnable examples to play with.

anyhow this is relativly hard stuff

chris

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Feb 18, 2011 Feb 18, 2011

Chris, I saw that post, fainted, fell over, got back up… and hoped I never need do that kind of math…   'relativly hard stuff' for me thats well above my station…

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Feb 18, 2011 Feb 18, 2011

Come on, give it at a try.

except the Intesection Stuff (i dont understand that too), the math is basic, really.

wikipedia  gives a good explanation about beziers if you ignore the text  (http://upload.wikimedia.org/wikipedia/commons/thumb/f/ff/Bezier_3_big.gif/240px-Bezier_3_big.gif)

i use this lib for everything where i need to handle positions, rotations and so on, not only on beziers.

for that the Point and Line objects are exellent.

it is unbelievable that they give us no POINTS, the coding with these pathPoints is so ....
i have no words for that

is this a graphicsProgram or what?

I think your main-problem with this lib is my lousy style and lazy commenting.

i have tried to make it a bit clearer with the demo functions.

at least it is not perfect, I'm sure some bugs are left over

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Feb 18, 2011 Feb 18, 2011

To be honest I have looked at this a few times and there are a few places where I understand what your doing. I understand the principles of beziers but when I look at this math…

http://en.wikipedia.org/wiki/Bézier_curve

then Im lost…   I will look again Im sure… Its the combination of a higher level of JavaScipting & higher level math…

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Feb 18, 2011 Feb 18, 2011

me too, but i dont use that.

i cant explain it in english...

i use a pure geometrical approach, pretty easy.

only linear interpolation.

look a while at the animated gif and you know what i mean

and/or run the function Demo(h)

but for the user it is not important

the other thing is to understand the prototyping chain

new Xpath(pathItem) contains Points,Beziers,etc.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Feb 18, 2011 Feb 18, 2011
LATEST

Chris, I have quite a few snippets of code that I have picked up from other posts along the way while trying to learn JavaScript thus far I have stayed away from using anything that prototypes objects. Again I can see in cases how this can add uses to things but until I have a better understanding of the implications involved I use a yard stick… I have not seen anything in my documents to say how long the additions persist what happens if several scripts use different ones or they mix? All sounds like I could end up in a big mess that I won't know how to fix… that or something I do will screw with other peoples scripts.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines