Skip navigation
Currently Being Moderated

Circular path

Aug 14, 2012 1:38 AM

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

function drawCircle(X,Y,rad, pathName)
{
var K = (4 * (Math.sqrt(2) - 1) / 3)* rad

// define circle points
var C = new Array();
C = [X, Y - rad, X + rad, Y, X, Y + rad, X - rad, Y, X + K, Y - rad, X + rad, Y - K, X + rad, Y + K, X - K, Y + rad, X + K, Y + rad, X - rad, Y + K, X - rad, Y - K, X - K, Y - rad];

// 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!

 
Replies
  • Currently Being Moderated
    Aug 14, 2012 1:52 AM   in reply to Ghoulfool

    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.

     
    |
    Mark as:
  • Currently Being Moderated
    Aug 14, 2012 6:01 AM   in reply to Ghoulfool

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

     
    |
    Mark as:
  • JJMack
    3,503 posts
    Jan 9, 2006
    Currently Being Moderated
    Aug 14, 2012 7:35 AM   in reply to Ghoulfool

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

    }

     

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points