Results 1 to 10 of 10

Thread: Spirograph

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Feb 2010


    My fellow ArtRagers, what key feature were you crushed to realize was left out of version 3.5?

    Is it vectors?

    Perspective options?

    A "Bob Ross" slider for the Oil Brush?


    It's a spirograph generator! But now you can fill the void. Simply copy and paste the below code into a UTF-16 text file per Andy's instructions. (edit: or, click on the file and save to your Scripts directory)

    The generator works on the current painting with your selected drawing tool (try it with eraser on a colored background). It should work with both 3.5 and 3.5 Pro.

    If you run into any problems, please let me know!

    edit on 8/3/11: made minor change to multicolor code, hopefully without breaking anything
    //                            ArtRage Script File.
    // Version Block - Script version and ArtRage version:
        ArtRage Version: ArtRage 3 Studio Pro
        ArtRage Build: 3.5.1
        Professional Edition: No
        Script Version: 1
    // Header block - Info about the painting/person who generated this script:
        // === Project data
        Painting Name: "untitled"
        Painting Width: 1280
        Painting Height: 1024
        Painting DPI: 72
        // === Author data
        Author Name: "Ti-Chen Feng"
        Script Name: "Epicycloid"
        Comment: "a 'spirograph' generator"
        Script Type: ""
        Script Feature Flags: 0
    // Script data follows:
    //function: changes the foreground color (this method of color variation does not work for some tools)
    void SetColor( real rAmount )  {
      real rHue = ColourH()
      if (rHue>1) rHue--
      SetColourHLS( rHue, ColourL(), ColourS() )
    //function: draws the epicycloid
    void DrawEpicycloid(int nRes, real R, real r, real d, real rCenterX, real rCenterY, real rReps, flag fColorChange)  {
    //set up initial values (at theta = 0 rad)
    flag fContinue = YES
    int i = 0
    int nTool = CurrentToolID()            //Done in main, but I couldn't take the idea of passing yet another parameter
    int nColType = 0                    //0=none, 1=normal, 2=paint, 3=ink
    real rColAmount = 0.004                //default
    real x = rCenterX + R + r + d
    real y = rCenterY
    real delta = 2*3.14159265/(nRes+1)
    real theta = 0
    real rPressure = 0.235
    //fudging to mimic the additional pressure exerted by user
    rPressure += CurrentToolSetting(0x0B2D05E34)
    if (rPressure>1) rPressure=1
    //Depending on drawing tool, set up multicolor type
    if( fColorChange )  {
      //default: pencil (precise off), crayon, chalk, tube, glitter (mc off), sticker spray
      nColType = 1
      //oil, felt pen, knife (flat or edge), roller, wc
      if( nTool==4900 || nTool==4904 || (nTool==4905 && CurrentToolSetting(0x0B2D05E60)<2) || nTool==4915 || nTool==4916 )  {
        nColType = 2
        rColAmount = 0.4
      //pencil (precise), airbrush, ink, gloop
      if( nTool==4901 || nTool==4914 || nTool==4917 || nTool==4918 )  {
        nColType = 3
        rColAmount = 0.09
      //knife (other), eraser, glitter (multicolor)
      if( (nTool==4905 && CurrentToolSetting(0x0B2D05E60)>1) || nTool==4906 || (nTool==4913 && CurrentToolSetting(0x0B2D05E3E)>0) )  {
        nColType = 0
    //MessageBox("color type = %%nColType")
    //The while loop lets user continue if the results are interesting
    //The stroke event is broken up to allow Undo
    while (rReps>0)  {
          <EventPt> Wait: 0.000s Loc: (x, y) Pr: rPressure Ti: 1 Ro: 0 Rv: NO Iv: NO </EventPt>
          <Recorded> No </Recorded>
      // MouseDown point
      Loc: (x, y) Pr: rPressure Ti: 1 Ro: 0 Rv: NO Iv: NO
      //Draw the requested number of iterations
      for (i=0; i<=rReps*nRes; i++)  {
        Loc: (x, y) Pr: rPressure Ti: 1 Ro: 0 Rv: NO Iv: NO
        x = rCenterX + (R+r)*cos(theta) + d*cos(((R+r)/r)*theta)
        y = rCenterY + (R+r)*sin(theta) + d*sin(((R+r)/r)*theta)
        if( nColType==1 )  SetColor(rColAmount)
      // MouseUp point.  
      Loc: (x, y) Pr: rPressure Ti: 1 Ro: 0 Rv: NO Iv: NO
      //Continue or stop?
      InputBox("Stationary circle: %%R\nMoving circle: %%r\nDrawing arm: %%d\nResolution: %%nRes\nNumber of cycles to draw (0-100)$$rReps")
      if( rReps>100 )  rReps=100
      if( nColType>1 )  SetColor(rColAmount)
    flag fGradient = NO                    //whether or not to change hue during stroke event
    flag fNewLayer = YES                //put epicycloid on a new layer or use the current layer?
    int nTool = CurrentToolID()            //user's selected tool
    int nResolution = 180                //how often to calculate (x,y) per cycle
    real rCycle = 9.01                    //how many cycles to draw per iteration (one cycle being 360 degrees around stator)
    real rMaxRadX = PaintingWidth()/2
    real rMaxRadY = PaintingHeight()/2
    real rMaxRad = rMaxRadX
    real rStaRad = 100                    //radius of stator
    real rRotRad = -45                    //radius of rotor; rotor is outside of stator if positive, inside if negative
    real rArmLen = -55                    //length of a drawing arm fixed at center of rotor; starts pointing out (pos) or in (neg)
    //Check to make sure selected tool is not: sampler, xform, text, fill, or select
    if( nTool==4909 || nTool==4910 || nTool==4919 || nTool==4921 || nTool==4922 )  {
      MessageBox("Please select an appropriate tool!")
    //Maxiumum allowed radius is half the height or width (whichever is greater) of the canvas
    if (rMaxRadY>rMaxRadX) rMaxRad=rMaxRadY
    InputBox("Radius of stationary circle$$rStaRad\nRadius of moving circle$$rRotRad\nDrawing arm length$$rArmLen\nResolution (2-360)$$nResolution\nNumber of cycles (1-100)$$rCycle\nMulticolor?$$fGradient\nDraw on new layer?$$fNewLayer")
    //Verify input values:
    //    Radius of stator must be positive. Clamp maximum radius so the epicycloid is visible
    if (rStaRad<0) rStaRad=-rStaRad
    if (rStaRad>rMaxRad) rStaRad=rMaxRad
    //    Clamp maximum radius of rotor. For hypotrochoid, clamp radius to rStaRad. 0 is disallowed.
    if (rRotRad>rMaxRad) rRotRad=rMaxRad
    if (rRotRad<-rStaRad) rRotRad=-rStaRad
    if (rRotRad==0) rRotRad=rStaRad/100
    //    Clamp drawing arm length.
    if (rArmLen>rMaxRad) rArmLen=rMaxRad
    if (rArmLen<-rMaxRad) rArmLen=-rMaxRad
    //    nResolution is from 2 (draws 2 points per cycle) to 360 (draws 360 points)
    if (nResolution<2) nResolution=2
    if (nResolution>360) nResolution=360
    //    Number of cycles per iteration can be from 0 to, say, 100
    if (rCycle<0) rCycle=0
    if (rCycle>100) rCycle=100
    //Make a new layer, if requested
    if (fNewLayer) Wait: 0   EvType: Command   CommandID: Add New Layer
    DrawEpicycloid(nResolution, rStaRad, rRotRad, rArmLen, rMaxRadX, rMaxRadY, rCycle, fGradient)
    P.S. Here are some spirograph apps on the Internet:
    Attached Files Attached Files
    Last edited by terrygillooly; 08-04-2011 at 02:37 PM. Reason: update code
    Cat Boxes, a web comic

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts