5 Replies Latest reply on Aug 14, 2012 8:19 AM by Ghoulfool

# Circular path

A while back I asked if anyone had messed about with scripting paths in Photoshop. I got little response. Anyway I persevered with the hope of creating a circle. Just for kicks, you understand (I must get out more). Turns out there isn't much info out there on the subject only that it's not possible to create a true circle with bezier curves. I've had a look it into it and I've managed a circular approximation with paths.

```// draw circular path
// use at your own risk
// Author: ghoulfool
// Thanks to G. Adam Stanislav for the kappa explanation
// Kappa Kappa Hey!

app.preferences.rulerUnits = Units.PIXELS;

// OPTIONALS
var radius = 150; // radius of the circle to be drawn
var circX = 160; // centre of circle X
var circY = 160; // centre of circle Y

//  create a document to work with
var docRef = app.documents.add("320px", "320px", 72, "Circle");

// call the source document
var srcDoc = app.activeDocument;

// create new layer
var layerRef = srcDoc.artLayers.add()
layerRef.name = "circle"
layerRef.blendMode = BlendMode.NORMAL

//draw circle
drawCircle(circX , circY, radius, "circle")

{
var K = (4 * (Math.sqrt(2) - 1) / 3)* rad

// define circle points
var C = new Array();

// create the array of PathPointInfo objects
var lineArray = new Array();
lineArray.push(new PathPointInfo());
lineArray[0].kind = PointKind.CORNERPOINT;

lineArray[0].anchor = new Array(C[0], C[1]); // A
lineArray[0].leftDirection =  [C[8], C[9]];
lineArray[0].rightDirection = lineArray[0].anchor;

lineArray.push(new PathPointInfo());
lineArray[1].kind = PointKind.CORNERPOINT;
lineArray[1].anchor = new Array(C[2], C[3]); // B

lineArray[1].leftDirection = [C[12], C[13]];
lineArray[1].rightDirection =  [C[10], C[11]];

lineArray.push(new PathPointInfo());
lineArray[2].kind = PointKind.CORNERPOINT;
lineArray[2].anchor = new Array(C[4], C[5]); // C

lineArray[2].leftDirection = [C[14], C[15]];
lineArray[2].rightDirection =  [C[16], C[17]];

lineArray.push(new PathPointInfo());
lineArray[3].kind = PointKind.CORNERPOINT;
lineArray[3].anchor = new Array(C[6], C[7]);    // D

lineArray[3].leftDirection = [C[20], C[21]];
lineArray[3].rightDirection =  [C[18], C[19]];

lineArray.push(new PathPointInfo());
lineArray[4].kind = PointKind.CORNERPOINT;
lineArray[4].anchor = new Array(C[0], C[1]);

lineArray[4].leftDirection = lineArray[4].anchor;
lineArray[4].rightDirection =  [C[22], C[23]];

// create a SubPathInfo object, which holds the line array in its entireSubPath property.
var lineSubPathArray = new Array();
lineSubPathArray.push(new SubPathInfo());
lineSubPathArray[0].operation = ShapeOperation.SHAPEXOR;
lineSubPathArray[0].closed = false;
lineSubPathArray[0].entireSubPath = lineArray;

//create the path item, passing subpath to add method
var myPathItem = docRef.pathItems.add(pathName, lineSubPathArray);

// set foreground colour to green
var fgColor = new SolidColor;
fgColor.rgb.hexValue="00ff80"  //green colour
foregroundColor = fgColor

//fill the path
myPathItem.fillPath(fgColor,ColorBlendMode.NORMAL,100,false,0,true,true);

//deselect path
// =======================================================
var id630 = charIDToTypeID( "Dslc" );
var desc154 = new ActionDescriptor();
var id631 = charIDToTypeID( "null" );
var ref127 = new ActionReference();
var id632 = charIDToTypeID( "Path" );
ref127.putClass( id632 );
desc154.putReference( id631, ref127 );
executeAction( id630, desc154, DialogModes.NO );
}

```

This was my second attempt. The first was on a semi circle basis with two points - but the circles looked very oval. This is much better I feel.

Enjoy!

• ###### 1. Re: Circular path

Turns out there isn't much info out there on the subject only that it's not possible to create a true circle with bezier curves.

Is that so indeed?

The Ellipse Tool (constrained) seems to create a decent crircular Path and if that is pasted above itself and rotated I cannot notice any misalignments.

1 person found this helpful
• ###### 2. Re: Circular path

I was well aware that you can convert the ellipsis tool to a path (make work path) but the resulting path is perfectly circular, but rather messy (in terms of point placement)

The whole point of the exercise was for me to gain a better understanding on how bezier paths work within scripting. So i'm happy.

• ###### 3. Re: Circular path

The result of the Ellipse Tool is a Path (with 4 points), did you mean the Elliptical Marquee Tool?

Edit: I mean the Ellipse Tool which is tertiary to the Rectangle Tool (U).

1 person found this helpful
• ###### 4. Re: Circular path

This would be very easy to do with scriptlistner code using either the elliptical marquee tool or elliptical tool. The elliptical tool can create a Path directly and the elliptical marquee tool can create selection which in turn can be turned in a path all can be transformed. The elliptical tool would create a better Path a circle would have 4 point.  Converting a slection is to a path would not work that well.

I created a plug-in script based on "Fit Image.jsx"  that combine the rectangle and elliptical selection tools so you can record making aspect ratio selection for documents in actions. The plugin http://www.mouseprints.net/old/dpr/AspectRatioSelection.jsx

/* ==========================================================

// Christmass 2007 John J. McAssey (JJMack) and the

// Day I descovered Photoshop had what I wanted

// a way to pass Prams to Scripts throught menu File>Automate

// ======================================================= */

/* SetMarqueeSelection function from Scriptlistner plugin

// ========================================================================== */

function setMarqueeSelection(x1, y1, x2, y2, type, shape, feather, antiAlias) {

var SelectionType =null;

if (type ==null)      {          var SelectionType = "setd" }

if (type ==diminish)  {          var SelectionType = "SbtF" }

if (type ==extend)    {          var SelectionType = "AddT" }

if (type ==intersect) {          var SelectionType = "IntW" }

if (type ==replace)   {          var SelectionType = "setd" }

var id3          = charIDToTypeID( SelectionType          );

var          desc2 =          new ActionDescriptor();

var          id4 = charIDToTypeID( "null" );

var ref1 = new ActionReference();

var id5          = charIDToTypeID( "Chnl" );

var id6          = charIDToTypeID( "fsel" );

ref1.putProperty( id5, id6 );

desc2.putReference(          id4, ref1 );

var          id7 = charIDToTypeID( "T   " );

var desc3 = new          ActionDescriptor();

var id8          = charIDToTypeID( "Top " );

var id9          = charIDToTypeID( "#Pxl" );

desc3.putUnitDouble( id8, id9, y1 );

var id10 = charIDToTypeID( "Left" );

var id11 = charIDToTypeID( "#Pxl" );

desc3.putUnitDouble( id10, id11, x1 );

var id12 = charIDToTypeID( "Btom" );

var id13 = charIDToTypeID( "#Pxl" );

desc3.putUnitDouble( id12, id13, y2 );

var id14 = charIDToTypeID( "Rght" );

var id15 = charIDToTypeID( "#Pxl" );

desc3.putUnitDouble( id14, id15, x2 );

var          id16 = charIDToTypeID( shape );

desc2.putObject( id7, id16,          desc3 );

var          id17 = charIDToTypeID( "Fthr" );

var          id18 = charIDToTypeID( "#Pxl" );

desc2.putUnitDouble( id17, id18, feather );

var          id19 = charIDToTypeID( "AntA" );

desc2.putBoolean( id19, antiAlias );

executeAction( id3, desc2, DialogModes.NO );

}

1 person found this helpful
• ###### 5. Re: Circular path

c.pfaffenbichler:

You're right about the ellipse tool. It does a good job. Yes....and there was a bit of confusion with Ellipse tool and Elliptical Marquee Tool.

1 person found this helpful