My curlicue fractal clock works 100% fine in Java mode, but as soon as I try to set the stroke or fill colour on Android, the sketch crashes as soon as it runs. I don't know if this is relevant, but I'm on a Moto G with Android 5.1, running sketches via Processing 3.2.1. Full code is below; the lines with setStroke and setFill are currently commented out so that it runs on Android.
Any ideas for a workaround? Should I file this as a bug report on GitHub? Thanks!
import java.util.Date;
/** Chronosynclastic Curlicue Cog Clock Clock
<p>Each curlicue has its period printed on it: the fastest loops right back to the top every five seconds.
The slowest takes one minute.
Their shapes tell a mathematical story.</p>
By Fergus Murray
*/
PShape cogShape;
float x, y, ox, oy, f, flipper=1, rot;
double df=0, ddf=0;
int i=0;
boolean drawDigitalClock=true, drawAnalogueClock=false, drawSecondCurlicues=true, drawDayCurlicue=true;
long startTime;
void setup() {
//fullScreen();
//size (displayHeight, displayHeight); // In case you want it in a square.
size (600, 600); // About right for use in a web page.
frameRate (24);
colorMode (HSB, 360); // So we can use hue, saturation and brightness
background (0, 0, 0);
Date theDate=new Date();
startTime=theDate.getTime(); // Our base time for calculating the clock
cogShape=createShape();
cogShape.beginShape ();
float radius=12; // The stroke weight for shapes seems to be stuck at 1 (?) so this mainly controls that, indirectly.
float cogPoints=12;
//float cogTeeth=6;
flipper=-1;
for (int i=0; i<cogPoints; i++) {
// Alternate way of making teeth, modulating the radius by a sine wave, produces puzzlingly asymmetrical star/flower-like cogs
//cogShape.vertex (radius*(1.0+0.8*cos(i*TAU*cogTeeth/cogPoints))*cos(i*TAU/cogPoints), radius*(1.0+0.8*cos(i*TAU*cogTeeth/cogPoints))*sin(i*TAU/cogPoints));
cogShape.vertex (radius*(1.0+0.2*flipper)*cos(i*TAU/cogPoints), radius*(1.0+0.2*flipper)*sin(i*TAU/cogPoints));
cogShape.vertex (radius*(1.0-0.2*flipper)*cos(i*TAU/cogPoints), radius*(1.0-0.2*flipper)*sin(i*TAU/cogPoints));
flipper=-flipper;
}
cogShape.rotate(PI/12);
cogShape.endShape(CLOSE);
orientation(PORTRAIT);
}
void draw() {
background(0);
// First, a digital clock
if (drawDigitalClock) {
fill(60, 248, 360);
textSize(42);
text(nf(hour(), 2)+" : "+nf(minute(), 2)+" : "+nf(second(), 2), width/2, height-84);
}
pushMatrix();
translate(width/2, height/2);
// curlicue (period, length, width, baseHue, hueRange, lines, degree)
if (drawDayCurlicue) {
curlicue (43200, 180, width/90, 40, 120, true, 2); // (1 rev/12 hours)
}
if (drawAnalogueClock) {
curlicue (43200, 1, width/5, 40, 0, true, 1); // (1 rev/12 hours)
curlicue (3600, 1, width/4, 150, 0, true, 1); // seconds (1 rev/minute)
curlicue (60, 1, width/4, 180, 0, true, 1); // seconds (1 rev/minute)
}
if (drawSecondCurlicues) {
for (float i=1; i<=12; i++) {
pushMatrix();
rotate (i*PI/6);
translate(0, -width/3);
rotate (-i*PI/6);
curlicue (i*5, 4+(int)(i), width/42, i*5, (int)(i*5), false, 2);
popMatrix();
}
}
//curlicue (31622400, 1080, 2, 40, 0, true, 2); // (1 rev/366 days)
popMatrix();
}
void curlicue(double period, int curlLength, float stepSize, float baseHue, int digit, boolean lines, int degree) {
rot=0;
ddf=(TWO_PI*(double)(startTime+millis())/(1000*period))%TWO_PI; // The time, as a fraction of the period
df=ddf;
if (curlLength==1) f=(float)df;
else f=0;
x=0;
y=0;
strokeWeight(16);
//lines=true;
flipper=0;
for (i=0; i<curlLength; i+=1) {
stroke (baseHue+((float)i/curlLength)*digit, 360, 360, 180);
//stroke (180);
if (i==11 && degree==1) {
stroke (360);
}
if (flipper==1) {
if (degree==1) {
f+=ddf;
} else if (degree==2) {
f+=df;
} else if (degree==3) {
f+=ddf*ddf;
}
df+=ddf;
}
ox=x;
oy=y;
x+=stepSize*sin(f);
y-=stepSize*cos(f);
if (lines) {
strokeWeight(4.5);
//stroke(300);
if (flipper!=2) { // I currently want to draw all the lines, but this is optional.
line(x, y, ox, oy);
}
if (i>0) {
strokeWeight(stepSize/8);
} else {
strokeWeight(24);
}
} else {
strokeWeight(stepSize/2);
}
fill(0);
pushMatrix();
translate(x, y);
rot=2*f-rot;
rotate(rot+flipper*PI/6);
//rotate((float)((f)*(1+flipper))); // Every other cog-marriage has the right alignment
// So angle2-angle1 is right when flipper goes + to - (or - to +?)
// The other half of the time the second cog isn't turning fast enough
// So the angle needs to increase by [ddf?] every time to compensate
textSize(14);
textAlign(CENTER, CENTER);
//cogShape.setStroke(120);
if (lines==false) {
fill (i*40, 360, 360);
//cogShape.setStroke(color((i*30)%360, 360, 360)); // Uncomment either of these lines and it crashes on Android
//cogShape.setFill(color(baseHue+((float)i/curlLength)*digit, 360*(0.5+flipper), 360));
shape(cogShape, 0, 0, stepSize*0.6, stepSize*0.6);
fill(0);
textSize(stepSize*0.4);
if (i<2) text(digit, -2, -1); // Print the period on the first two cogs
}
popMatrix();
flipper=1-flipper;
}
}
void keyPressed() {
if (key=='s') save("Chrono-"+hour()+"-"+minute()+"-"+second()+"-"+millis()+".png");
}