# Illustrator Scripting

Currently Being Moderated

## Sorting out path items

### Apr 14, 2012 4:46 AM

Tags:

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!

Replies
• Currently Being Moderated
Apr 14, 2012 6:18 AM   in reply to LemonJoe

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…

|
Mark as:
• Currently Being Moderated
Apr 14, 2012 7:21 AM   in reply to LemonJoe

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...)

|
Mark as:
• Currently Being Moderated
Apr 14, 2012 9:23 AM   in reply to LemonJoe

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…

|
Mark as:
• Currently Being Moderated
Apr 19, 2012 8:05 PM   in reply to LemonJoe

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])){

// 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.");

}

|
Mark as:
• Currently Being Moderated
Apr 19, 2012 8:17 PM   in reply to Silly-V

Sorry for huge pictures : /

|
Mark as:
Actions

#### More Like This

• Retrieving data ...

#### Answers + Points = Status

• 10 points awarded for Correct Answers