/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.K$AiFTLVl9D/rev.24
*
* authors:
* Peter Hanley
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
// arrays to hold ellipse coordinate data
float[] px, py, cx, cy, cx2, cy2;
float thex, they;
float theAngle, angle2;
float radius;
// lower freq for slower, higher for faster
float frequency = 10;
float frequency2 = 10;
float x, x2;
// global variable-points in ellipse
int pts = 4;
// some environmental control
boolean canhasPause = false;
boolean palletteBackground = false;
int paletteSelector = int(random(10));
color[] thisColor = new color[5];
color theBackGroundColor;
color controlPtCol = colorFromPalette();
color anchorPtCol = colorFromPalette();
void setup() { // this is run once.
size(400, 400);
//size(1680,1050);
smooth();
// init thex and they coordinates
thex = width/2 + cos(radians(theAngle))*(radius/2);
they = height/2 + sin(radians(theAngle))*(radius/2);
//background(int(random(255)));
//sort out some colors
paletteSelector = int(random(10));
theBackGroundColor = colorFromPalette();
stroke(colorFromPalette());
// get a pallette background color if the user presses 'b' or 'B'
if (palletteBackground) {background(theBackGroundColor); }
else { background(255);}
rectMode(CENTER);
setEllipse(pts, 65, 65);
radius = width-10;
frameRate(10);
}
void draw() { // this is run repeatedly.
smooth();
drawEllipse();
if (frameCount % 2 == 0){
setEllipse(int(random(3, 12)), random(-100, 150), random(-100, 150));
}
else {
setEllipse(int(random(thex-thex/2, thex)), random(-they/2, they/2), random(-100, 150));
}
theAngle += frequency;
x+=1;
thex = width/2 + cos(radians(theAngle))*(radius/2);
they = height/2 + sin(radians(theAngle))*(radius/2);
//println("thex: " +thex+ " , they: " + they + " theAngle: " + theAngle);
}
// draw ellipse with anchor/control points
void drawEllipse(){
float radius = 100;
float angle = 0;
strokeWeight(1);
stroke(colorFromPalette(), 20);
noFill();
// create ellipse
for (int i=0; i<pts; i++){
if (i==pts-1) {
//bezier(px[i], py[i], cx[i], cy[i], cx2[i], cy2[i], px[0], py[0]);
bezier(thex, they, cx[i], cy[i], cx2[i], cy2[i], px[0], py[0]);
}
else{
//bezier(px[i], py[i], cx[i], cy[i], cx2[i], cy2[i], px[i+1], py[i+1]);
bezier(thex, they, cx[i], cy[i], cx2[i], cy2[i], px[i+1], py[i+1]);
}
}
strokeWeight(1);
stroke(colorFromPalette(), 20);
//stroke(int(random(255)), 140, 140, 20);
//
rectMode(CENTER);
// control handles and tangent lines
for ( int i=0; i< pts; i++){
if (i==pts-1){ // last loop iteration-close path
line(px[0], py[0], cx2[i], cy2[i]);
}
if (i>0){
line(px[i], py[i], cx2[i-1], cy2[i-1]);
}
line(px[i], py[i], cx[i], cy[i]);
}
for ( int i=0; i< pts; i++){
fill(colorFromPalette(), 5);
noStroke();
//control handles
ellipse(cx[i], cy[i], 4, 4);
ellipse(cx2[i], cy2[i], 4, 4);
fill(colorFromPalette());
stroke(colorFromPalette(), 2);
//anchor points
//rect(px[i], py[i], 5, 5);
}
}
// fill up arrays with ellipse coordinate data
void setEllipse(int points, float radius, float controlRadius){
pts = points;
px = new float[points];
py = new float[points];
cx = new float[points];
cy = new float[points];
cx2 = new float[points];
cy2 = new float[points];
float angle = 360.0/points;
float controlAngle1 = angle/3.0;
float controlAngle2 = controlAngle1*2.0;
for ( int i=0; i<points; i++){
px[i] = width/2+cos(radians(angle))*radius;
py[i] = height/2+sin(radians(angle))*radius;
cx[i] = width/2+cos(radians(angle+controlAngle1))*
controlRadius/cos(radians(controlAngle1));
cy[i] = height/2+sin(radians(angle+controlAngle1))*
controlRadius/cos(radians(controlAngle1));
cx2[i] = width/2+cos(radians(angle+controlAngle2))*
controlRadius/cos(radians(controlAngle1));
cy2[i] = height/2+sin(radians(angle+controlAngle2))*
controlRadius/cos(radians(controlAngle1));
//increment angle so trig functions keep chugging along
angle+=360.0/points;
//
}
}
void mousePressed(){
canhasPause = !canhasPause;
if (canhasPause)
noLoop();
else
loop();
}
void keyPressed(){
//println("keypressed = " + key);
if (key == 'q' || key == 'Q') {
setup();
}
if (key == 's' || key == 'S') {
save("liner" + frameCount + ".png");
//println("Saving file.");
//pikcha.save( "mBoverlay" + frameCount + ".png" );
// println("Saving overlay.");
}
}
// palette & color functions
color colorFromPalette(){
int pickThis = int(random(0, 4));
if (paletteSelector== 0){
thisColor[0] = color(#D7CEBF);
thisColor[1] = color(#B6B098);
thisColor[2] = color(#986B41);
thisColor[3] = color(#56342A);
thisColor[4] =color( #1B242B);
}
if (paletteSelector== 1){
thisColor[0] = color(#D7CEBF);
thisColor[1] = color(#B6B098);
thisColor[2] = color(#986B41);
thisColor[3] = color(#56342A);
thisColor[4] =color( #1B242B);
}
if (paletteSelector== 2){
thisColor[0] = color(98,98,44);
thisColor[1] = color(133,140,98);
thisColor[2] = color(234,194,73);
thisColor[3] = color(193,64,42);
thisColor[4] = color(221.115,91);
}
if (paletteSelector== 3){
thisColor[0] = color(#CCB24C);
thisColor[1] = color(#F7D683);
thisColor[2] = color(#FFFDC0);
thisColor[3] = color(#FFFFFD);
thisColor[4] = color(#457D97);
}
// colour lovers http://www.colourlovers.com/palette/1179957/kimono_streets
if (paletteSelector== 4){
thisColor[0] = color(#A0B6CB);
thisColor[1] = color(#FDFEEE);
thisColor[2] = color(#FAEAD0);
thisColor[3] = color(#FF460D);
thisColor[4] = color(#00A7E1);
}
// http://www.colourlovers.com/palette/1180315/c_a_l_a_b_r_i_a
if (paletteSelector == 5){
thisColor[0] = color(#FA1B3C);
thisColor[1] = color(#E35E54);
thisColor[2] = color(#FAA13D);
thisColor[3] = color(#75E1D8);
thisColor[4] = color(#6D6769);
}
if (paletteSelector== 6){
thisColor[0] = color(#A0B6CB);
thisColor[1] = color(#FDFEEE);
thisColor[2] = color(#FAEAD0);
thisColor[3] = color(#FF460D);
thisColor[4] = color(#00A7E1);
}
if (paletteSelector== 7){
thisColor[0] = color(#F34F4F);
thisColor[1] = color(#FF8F8F);
thisColor[2] = color(#E69F7F);
thisColor[3] = color(#E4D7A2);
thisColor[4] = color(#FFD500);
}
// http://www.colourlovers.com/palette/1002244/Mom_2
if (paletteSelector== 8){
thisColor[0] = color(#FFFFFF);
thisColor[1] = color(#D9CAB8);
thisColor[2] = color(#4C8582);
thisColor[3] = color(#303635);
thisColor[4] = color(#2B1B07);
}
// http://www.colourlovers.com/palette/101436/mom
if (paletteSelector== 9){
thisColor[0] = color(#C9AB9F);
thisColor[1] = color(#C4C0A7);
thisColor[2] = color(#99AAA3);
thisColor[3] = color(#695269);
thisColor[4] = color(#B88F9B);
}
//http://www.colourlovers.com/palette/452030/you_will_be_free
if (paletteSelector== 10){
thisColor[0] = color(#F7F9FE);
thisColor[1] = color(#ECF1F2);
thisColor[2] = color(#DCE8EB);
thisColor[3] = color(#CBDBE0);
thisColor[4] = color(#BED2D9);
}
//println(str(thisColor[pickThis]));
return thisColor[pickThis];
}
///////////////////////////////////// paletteShow
void paletteShow(){
stroke(255);
fill(thisColor[0]);
rect(10,560,20,20);
fill(thisColor[1]);
rect(35,560,20,20);
fill(thisColor[2]);
rect(60,560,20,20);
fill(thisColor[3]);
rect(85,560,20,20);
fill(thisColor[4]);
rect(110,560,20,20);
}
void paletteShow(int heightFromTop, int widthFromLeft){
stroke(255);
fill(thisColor[0]);
rect(widthFromLeft + 10,heightFromTop,20,20);
fill(thisColor[1]);
rect(widthFromLeft + 35,heightFromTop,20,20);
fill(thisColor[2]);
rect(widthFromLeft + 60,heightFromTop,20,20);
fill(thisColor[3]);
rect(widthFromLeft + 85,heightFromTop,20,20);
fill(thisColor[4]);
rect(widthFromLeft + 110,heightFromTop,20,20);
}
void paletteShow(int heightFromTop, int widthFromLeft, PGraphics buffer){
heightFromTop = height - 40;
widthFromLeft = 20;
stroke(255);
buffer.fill(thisColor[0]);
buffer.rect(widthFromLeft + 10,heightFromTop,20,20);
buffer.fill(thisColor[1]);
buffer.rect(widthFromLeft + 35,heightFromTop,20,20);
buffer.fill(thisColor[2]);
buffer.rect(widthFromLeft + 60,heightFromTop,20,20);
buffer.fill(thisColor[3]);
buffer.rect(widthFromLeft + 85,heightFromTop,20,20);
buffer.fill(thisColor[4]);
buffer.rect(widthFromLeft + 110,heightFromTop,20,20);
}
///////////////////////////////////// oppositeColor
color oppositeColor(color thisColor){
// from http://dotnetpulse.blogspot.com/2007/01/function-to-calculate-opposite-color.html
color thatColor;
return thatColor = color( red(thisColor) - 128 % 255, green(thisColor) - 128 % 255, blue(thisColor) - 128 % 255 );
}
color oppositeColor(color thisColor, String theMethod){
color thatColor = color(0,0,0);
if (theMethod == "RGB") {
return thatColor = color( red(thisColor) - 128 % 255, green(thisColor) - 128 % 255, blue(thisColor) - 128 % 255 );
}
if (theMethod == "HSB") {
// get the hue and add 180
float thisHue = hue(thisColor) + 180;
// to ensure a valid color, conform the return range to 0-360
while (thisHue > 360) {
if (thisHue > 360) { thisHue = thisHue - 360; }
}
// return the opposite color
thatColor = color(thisHue, saturation(thisColor), brightness(thisColor));
// uncomment the following line if you wish to see the values
// println("thisColor(hsb): " + " " + hue(thisColor) + " " + saturation(thisColor) + " " + brightness(thisColor) + " - thatColor(hsb)= " + hue(thatColor) + " " + saturation(thatColor) + " " + brightness(thatColor) );
return thatColor;
}
return thatColor;
}