8 Replies Latest reply: Apr 19, 2012 10:43 PM by LemonJoe RSS

    Sorting out path items

    LemonJoe

      Hello everyone!

      I have a collection of circles and rectangles in my document. Is there any way to sort out circles from rectagles using JavaScript? Say i want to make my circles red and the rectangles blue. Yes, yes i am a total beginner in coding Thank you in advance!

        • 1. Re: Sorting out path items
          Muppet Mark Community Member

          Hello, you have in fact just the one collection of path items… There are NO rectangles, circles, or polygons except for path item creation. After they have been made you would have to use the path points and some geometery math to work out what is what…

          • 2. Re: Sorting out path items
            LemonJoe Community Member

            Thank you, Muppet Mark. I suspected that there is no 'figures' after the path is created, now a i know it for a fact.

            • 3. Re: Sorting out path items
              [Jongware] CommunityMVP

              If you are certain that your document contains only rectangles and/or circles, you can inspect the paths of each objects to determine the what is what:

               

              only circle path points will contain bezier (curved) points.

               

              BUT if you have *any* number of *any* random kind of objects, you need to check MUCH more. A rectangle always will have at least four corner points (it may have more, if some points are colinear or even coincident); all corners need to have an angle of 90 degrees. You cannot just test for equal x/y coordinates because a rotated rectangle is still a rectangle.

               

              A circle also has (at least) 4 points, but they all need to be of the bezier type. "Circles", by the way, are not an Illustrator primitive object; they are *approximated* through four bezier curves. Therefore you'd need to test the curvature of each bezier curve, and allow for some error in the approximation. (Draw a circle in Illustrator. Drag out one of the bezier control points by a small amount. Is it still a circle? ... Considering it wasn't one to begin with...)

              • 4. Re: Sorting out path items
                LemonJoe Community Member

                I understand the method. Defiining a figure by finding some of it's inherent properties. It was my 'hard' way, asking i hoped there is an 'easy' way Thank you!

                • 5. Re: Sorting out path items
                  Muppet Mark Community Member

                  I will hold my hands up and say when I first started with scripting with AI… I looked at making functions to determine/test basic shapes neadless to say it was actually far more complicated than I had originaly thought and duly gave up… Circle, rectangle & square all a 4 path point array [ , , , ] Feel free to work that up a little…

                  • 6. Re: Sorting out path items
                    Silly-V Community Member

                    Take two!  Now with most advanced-basic shape detection ever! 

                     

                    /*------------------------------------Circle or Rectangle---------------------------------------*/

                    // Finds perfect circles and/or rectangles in document and  colors them.

                    // Silly-V

                     

                    function makeCmykColor(c, m, y, k)  // Handy color-making function.

                    {

                        var newCmykColor = new CMYKColor();

                            newCmykColor.cyan = c;

                            newCmykColor.magenta = m;

                            newCmykColor.yellow = y;

                            newCmykColor.black =  k;

                        return newCmykColor;

                    }

                     

                     

                    if(app.documents.length > 0){

                        var doc = app.documents[0];

                        var myShapes = new Array();

                        for (i=0; i<doc.pageItems.length; i++){

                            var myShape = doc.pageItems[i];

                            myShapes.push(myShape);

                            if (myShape.typename == "PathItem"){

                                if (myShape.pathPoints.length == 4){ // RECTANGLE CHECKER

                                    //--------------------2 diagonals-------------------------

                                    var recEquaDistOne = parseInt(Math.pow((myShape.pathPoints[0].anchor[0] - myShape.pathPoints[2].anchor[0]),2) +

                                    Math.pow((myShape.pathPoints[0].anchor[1] - myShape.pathPoints[2].anchor[1]),2)); // diagonal

                                    var recEquaDistTwo = parseInt(Math.pow((myShape.pathPoints[1].anchor[0] - myShape.pathPoints[3].anchor[0]),2) +

                                    Math.pow((myShape.pathPoints[1].anchor[1] - myShape.pathPoints[3].anchor[1]),2)); // diagonal

                                    //---------------------4 sides of rectangle---------------

                                    var sideA = parseInt(Math.pow((myShape.pathPoints[0].anchor[0] - myShape.pathPoints[1].anchor[0]),2) +

                                    Math.pow((myShape.pathPoints[0].anchor[1] - myShape.pathPoints[1].anchor[1]),2)); 

                                    var sideB = parseInt(Math.pow((myShape.pathPoints[1].anchor[0] - myShape.pathPoints[2].anchor[0]),2) +

                                    Math.pow((myShape.pathPoints[1].anchor[1] - myShape.pathPoints[2].anchor[1]),2)); 

                                    var sideC = parseInt(Math.pow((myShape.pathPoints[2].anchor[0] - myShape.pathPoints[3].anchor[0]),2) +

                                    Math.pow((myShape.pathPoints[2].anchor[1] - myShape.pathPoints[3].anchor[1]),2)); 

                                    var sideD = parseInt(Math.pow((myShape.pathPoints[3].anchor[0] - myShape.pathPoints[0].anchor[0]),2) +

                                    Math.pow((myShape.pathPoints[3].anchor[1] - myShape.pathPoints[0].anchor[1]),2)); 

                                    if (recEquaDistOne == recEquaDistTwo){ // If two diagonals connecting opposite points are same length, it's a 90 degree box               

                                        if ((sideA == sideC) && (sideB == sideD)){

                                        for (j=0; j<4; j++){

                                            var point = myShape.pathPoints[j];             

                                                if ((point.leftDirection[0] == point.anchor[0]) &&

                                                    (point.anchor[0] == point.rightDirection[0]) &&

                                                    (point.leftDirection[1] == point.anchor[1]) &&

                                                    (point.anchor[1] == point.rightDirection[1])){                                                   

                                                    myShape.isrectangle = true;

                                                    } else {

                                                    myShape.isrectangle = false;

                                                    break;

                                                    }

                                                }

                                            }

                                        }

                                    }

                                if (myShape.pathPoints.length == 4){  // CIRCLE CHECKER

                                    if (myShape.isrectangle == false || myShape.isrectangle == null){

                                    var circlePts = new Array();

                                    var circleSlopes = new Array();

                                    for (k=0; k<4; k++){

                                    var point = myShape.pathPoints[k]; 

                                    var leftHandleDist = parseInt(Math.pow((point.leftDirection[0] - point.anchor[0]),2) +

                                    Math.pow((point.leftDirection[1] - point.anchor[1]),2));

                                    var rightHandleDist = parseInt(Math.pow((point.rightDirection[0] - point.anchor[0]),2) +

                                    Math.pow((point.rightDirection[1] - point.anchor[1]),2));

                                    circlePts.push(leftHandleDist, rightHandleDist);

                                    var leftHandleSlope = ((point.leftDirection[0] - point.anchor[0])/(point.leftDirection[1] - point.anchor[1])).toFixed(2);

                                    var rightHandleSlope = ((point.rightDirection[0] - point.anchor[0])/(point.rightDirection[1] - point.anchor[1])).toFixed(2);

                                    circleSlopes.push(leftHandleSlope, rightHandleSlope);

                                    }

                                    for (f=0; f<8; f++){ // Allows non-rotated circles.

                                        if (circleSlopes[f] == "-0.00"){

                                             circleSlopes[f] = "0.00";

                                             }

                                        if (circleSlopes[f] == "-Infinity"){

                                             circleSlopes[f] = "Infinity";

                                             }

                                     }

                                    //$.write(circleSlopes[0] + " , " + circleSlopes[1] + "  | " + circleSlopes[2] + " , " + circleSlopes[3] +

                                    //" | " + circleSlopes[4] + " , " + circleSlopes[5] + " | " + circleSlopes[6] +  " , " + circleSlopes[7] + " " + myShape.name + " \r");

                                    //$.write("(" + circlePts[0] + ", " + circlePts[1] + ") (" + circlePts[2] + ", " + circlePts[3]

                                    //+ ") (" + circlePts[4] + ", " + circlePts[5] + ") (" + circlePts[6] + ", " + circlePts[7] + ")\r");           

                                    var cirEquaDistOne = parseInt(Math.pow((myShape.pathPoints[0].anchor[0] - myShape.pathPoints[2].anchor[0]),2) +

                                    Math.pow((myShape.pathPoints[0].anchor[1] - myShape.pathPoints[2].anchor[1]),2));

                                    var cirEquaDistTwo = parseInt(Math.pow((myShape.pathPoints[1].anchor[0] - myShape.pathPoints[3].anchor[0]),2) +

                                    Math.pow((myShape.pathPoints[1].anchor[1] - myShape.pathPoints[3].anchor[1]),2));

                                    if (circleSlopes[0] != "NaN"){ // Filters out asymmetric rhombus  <><><>^^^^^^<><><>

                                        if ((circlePts[0] == circlePts[1]) && // Filters out shapes with control handles not of equal distance from anchor point.

                                            (circlePts[1] == circlePts[2]) &&

                                            (circlePts[2] == circlePts[3]) &&

                                            (circlePts[3] == circlePts[4]) &&

                                            (circlePts[4] == circlePts[5]) &&

                                            (circlePts[5] == circlePts[6]) &&

                                            (circlePts[6] == circlePts[7]) &&

                                            (circlePts[7] == circlePts[0])){

                                                if((circleSlopes[0] == circleSlopes[1]) && // Filters out the equadistant 4-pointed Star shape (dismisses negative slopes).

                                                    (circleSlopes[2] == circleSlopes[3]) &&

                                                    (circleSlopes[4] == circleSlopes[5]) &&

                                                    (circleSlopes[6] == circleSlopes[7])){                           

                                                        if (cirEquaDistOne == cirEquaDistTwo){ // Filters out Ellipses (non-equadistant circles).

                                                            // Filters out the very RARE 4-pointed star which has all control points in its center on top of each other!

                                                            if (((myShape.pathPoints[0].leftDirection[0]).toFixed(2) != (myShape.pathPoints[1].leftDirection[0]).toFixed(2)) &&

                                                                ((myShape.pathPoints[0].leftDirection[1]).toFixed(2) != (myShape.pathPoints[1].leftDirection[1]).toFixed(2))){

                                                                myShape.iscircle = true;

                                                                } else {

                                                                myShape.iscircle = false;

                                                            }

                                                        }

                                                    }

                                                }                   

                                            }

                                        }

                                    }

                                }

                            }

                        for (x=0; x<myShapes.length ; x++){ // PROCESSING --> Now that shapes are marked, do what you want! 

                            // ** Compound Paths:  They favor top-most shape color attributes **

                            if (myShapes[x].isrectangle == true){ //$.writeln("A rectangle has been detected! " + [x]);

                                if(myShapes[x].filled == true){

                                myShapes[x].fillColor = makeCmykColor (0, 100, 100, 0);

                                }

                                if(myShapes[x].stroked == true){

                                myShapes[x].strokeColor = makeCmykColor (0, 100, 100, 0);

                                }

                            }

                            if (myShapes[x].iscircle == true){ //$.writeln("A circle has been detected! " + [x]);

                                if(myShapes[x].filled == true){

                                myShapes[x].fillColor = makeCmykColor (100, 100, 0, 0);

                                }

                                if(myShapes[x].stroked == true){

                                myShapes[x].strokeColor = makeCmykColor (100, 100, 0, 0);

                                }

                            }

                        }

                    }else {

                    alert("Please open up a document with some circles and rectangles & re-run.");

                    }

                     

                    Before.jpgAfter.jpg

                    • 7. Re: Sorting out path items
                      Silly-V Community Member

                      Sorry for huge pictures : /

                      • 8. Re: Sorting out path items
                        LemonJoe Community Member

                        WOW Awsome! Your first one was very helpfull, I guess this one closes the subject completely. Thanks man!