[Scripting] Dividing an object path via Javascript / ExtendScript

New Here ,
Apr 14, 2022 Apr 14, 2022

Copy link to clipboard

Copied

Say I have a circle drawn to the centre of a 1080 x 1080px artboard (as in the attached screenshot).

 

Is there a way to programatically divide the circle at the point of each of its anchor points -- into 4 separate paths?

 

If i were to do this in Illustrator itself i'd use the scissor tool -- but wondering how i could do this with a script. I've looked at the https://ai-scripting.docsforadobe.dev/ documentation but can't find anything relevant.

TOPICS
How to , Scripting

Views

115

Likes

Translate

Translate

Report

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
Adobe Community Professional ,
Apr 14, 2022 Apr 14, 2022

Copy link to clipboard

Copied

You create additional paths at the respective angles and invoke a Pathfinder operation, completely reconstruct the path by fetching its underlying Bèzier values for tha anchor points or simply or simply duplicate the layer and delete extraneous points. Whatever is the best approach for you. I'm also sure there is already some clever "unjoin anchor points" script or something liek that out there plus some plug-ins offer such useful little tricks.

 

Mylenium

Likes

Translate

Translate

Report

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
Enthusiast ,
Apr 14, 2022 Apr 14, 2022

Copy link to clipboard

Copied

Hi, do you mean like pizza slices, or just the standalone arcs? The relevant pages in those online docs would be PathItem, PathPoints, and PathPoint:

 

diagram.png

Slice result being:

result.png

And a script example which should be relatively easy to understand for someone starting out with scripting:

 

function subDivideToCenter(item) {
    var bounds = item.geometricBounds, // we need the bounds
        // The left edge plus half it's width is center:
        centerX = bounds[0] + ((bounds[2] - bounds[0]) / 2),
        // Top edge plus half it's height is center:
        centerY = bounds[1] + ((bounds[3] - bounds[1]) / 2),
        centerPoint = [centerX, centerY]; // we need this coordinate since this is a point in our upcoming slices

    // So we iterate over each of the pathPoints
    for (var p = 0; p < item.pathPoints.length; p++) {
        // And grab the current point and the next point:
        var point = item.pathPoints[p],
            nextPoint = item.pathPoints[(p + 1) % item.pathPoints.length];
        // The above is a fancy way of saying add 1 to the number unless it's the last, then be 0

        /**
         * We know the points needed for pizza-like slicing:
         *   - Any given point and one of it's handles
         *   - The next point and it's own opposite handle pointing inwards
         *   - The centerpoint
         * 
         * So we can make the list explicitly:
         */
        var pointsList = [
            // 0:
            {
                anchor: point.anchor,
                leftDirection: point.anchor, // We don't want this curve
                rightDirection: point.rightDirection // We only want this one, towards the next point
            },
            // 1:
            {
                anchor: nextPoint.anchor,
                leftDirection: nextPoint.leftDirection, // This is the opposite curve from prior
                rightDirection: nextPoint.anchor, // And we ignore this one
            },
            // 2:
            {
                // Then our last point is just the center of the shape with no curves:
                anchor: centerPoint, 
                leftDirection: centerPoint,
                rightDirection: centerPoint
            }
        ];
        // Add a new shape:
        var slice = app.activeDocument.pathItems.add();
        // Then iterate through the pointsList above:
        for (var n = 0; n < pointsList.length; n++) {
            var pointData = pointsList[n],
                newPoint = slice.pathPoints.add();
            // And set the keys of the PathPoint object explicitly:
            newPoint.anchor = pointData.anchor;
            newPoint.leftDirection = pointData.leftDirection;
            newPoint.rightDirection = pointData.rightDirection;
        }
        // To connect the centerpoint back to the original for a slice, we set it as a closed shape:
        slice.closed = true;
    }
    // To remove the original shape, uncomment this line:
    // item.remove();
}

// We trigger the main function on the first selected object, like an ellipse:
subDivideToCenter(app.selection[0]);

 

 

If you mean the arcs only without connecting back to the centerpoint then it's the same exact code, you'd just delete the last object from the pointsList array:

 

// 2:
{
    // Then our last point is just the center of the shape with no curves:
    anchor: centerPoint, 
    leftDirection: centerPoint,
    rightDirection: centerPoint
}

 

And this line at the very end of the function:

 

// To connect the centerpoint back to the original for a slice, we set it as a closed shape:
slice.closed = true;

 

 

Likes

Translate

Translate

Report

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
Advocate ,
Apr 14, 2022 Apr 14, 2022

Copy link to clipboard

Copied

This should split a path into it's segments.

// select path
var path1 = app.activeDocument.selection[0];
var points = path1.pathPoints;
if (path1.closed) var cap = points.length;
else var cap = points.length - 1;
for (var i = 0; i < cap; i++) {
    var path2 = app.activeDocument.pathItems.add();
    var p1 = path2.pathPoints.add();
    p1.anchor = points[i].anchor;
    p1.rightDirection = points[i].rightDirection;
    p1.leftDirection = points[i].leftDirection;
    var p2 = path2.pathPoints.add();
    if (path1.closed && i == cap - 1) {
        p2.anchor = points[0].anchor;
        p2.rightDirection = points[0].rightDirection;
        p2.leftDirection = points[0].leftDirection;
    } else {
        p2.anchor = points[i + 1].anchor;
        p2.rightDirection = points[i + 1].rightDirection;
        p2.leftDirection = points[i + 1].leftDirection;
    }
}
path1.remove();

Likes

Translate

Translate

Report

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
Adobe Community Professional ,
Apr 14, 2022 Apr 14, 2022

Copy link to clipboard

Copied

LATEST

It's pretty easy to do it manually, but of course you can make a simple action that would:

 

- Select the path(s)

- Select menu > Object > Direction Handles

- Edit menu > Cut

- Edit menu > Clear

- Edit menu > Paste in Front

 

If you are rather looking for pizza shapes, it can be done with a simple graphic style.

 

Likes

Translate

Translate

Report

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