terrygillooly
07-26-2011, 02:39 PM
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?
Wrong!
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 (http://www2.ambientdesign.com/forums/showthread.php?t=35944). (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:
//================================================== =========================
<Version>
ArtRage Version: ArtRage 3 Studio Pro
ArtRage Build: 3.5.1
Professional Edition: No
Script Version: 1
</Version>
//================================================== =========================
// Header block - Info about the painting/person who generated this script:
//================================================== =========================
<Header>
// === 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
</Header>
//================================================== =========================
// 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()
rHue+=rAmount
if (rHue>1) rHue--
SetColourHLS( rHue, ColourL(), ColourS() )
return
}
//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) {
<StrokeEvent>
<StrokeHeader>
<EventPt> Wait: 0.000s Loc: (x, y) Pr: rPressure Ti: 1 Ro: 0 Rv: NO Iv: NO </EventPt>
<Recorded> No </Recorded>
</StrokeHeader>
// 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)
theta+=delta
if( nColType==1 ) SetColor(rColAmount)
}
// MouseUp point.
Loc: (x, y) Pr: rPressure Ti: 1 Ro: 0 Rv: NO Iv: NO
</StrokeEvent>
//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)
}
return
}
<Events>
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!")
exit
}
//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
//Draw!
DrawEpicycloid(nResolution, rStaRad, rRotRad, rArmLen, rMaxRadX, rMaxRadY, rCycle, fGradient)
//110803
P.S. Here are some spirograph apps on the Internet:
http://www.mathplayground.com/SpirographMath.html
http://www.math.psu.edu/dlittle/java/parametricequations/spirograph/SpiroGraph1.0/index.html
http://perl.guru.org/lynn/apps/
Is it vectors?
Perspective options?
A "Bob Ross" slider for the Oil Brush?
Wrong!
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 (http://www2.ambientdesign.com/forums/showthread.php?t=35944). (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:
//================================================== =========================
<Version>
ArtRage Version: ArtRage 3 Studio Pro
ArtRage Build: 3.5.1
Professional Edition: No
Script Version: 1
</Version>
//================================================== =========================
// Header block - Info about the painting/person who generated this script:
//================================================== =========================
<Header>
// === 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
</Header>
//================================================== =========================
// 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()
rHue+=rAmount
if (rHue>1) rHue--
SetColourHLS( rHue, ColourL(), ColourS() )
return
}
//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) {
<StrokeEvent>
<StrokeHeader>
<EventPt> Wait: 0.000s Loc: (x, y) Pr: rPressure Ti: 1 Ro: 0 Rv: NO Iv: NO </EventPt>
<Recorded> No </Recorded>
</StrokeHeader>
// 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)
theta+=delta
if( nColType==1 ) SetColor(rColAmount)
}
// MouseUp point.
Loc: (x, y) Pr: rPressure Ti: 1 Ro: 0 Rv: NO Iv: NO
</StrokeEvent>
//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)
}
return
}
<Events>
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!")
exit
}
//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
//Draw!
DrawEpicycloid(nResolution, rStaRad, rRotRad, rArmLen, rMaxRadX, rMaxRadY, rCycle, fGradient)
//110803
P.S. Here are some spirograph apps on the Internet:
http://www.mathplayground.com/SpirographMath.html
http://www.math.psu.edu/dlittle/java/parametricequations/spirograph/SpiroGraph1.0/index.html
http://perl.guru.org/lynn/apps/