/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.BjiClPprsV-/rev.76
*
* authors:
* Nick Bennett
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
boolean DEBUG = false;
int loopsPerFrame = 1;
color bgColor = color(0);
color fgColor1, fgColor2;
float centerX, centerY;
// number of pairs of divisions, as
// sample section is mirrored once and
// total number is multiple of two
float radialDivisions = 18;
float divisionAngle = (2 * PI) / (2 * radialDivisions);
void setup() {
size(400, 300);
// size(screen.width, screen.height, P2D);
colorMode(HSB, 255);
fgColor1 = color(random(255), random(192, 255), 255);
// fgColor2 = color(random(255), random(255), random(255));
fgColor2 = color((hue(fgColor1) + 127)%255, saturation(fgColor1), brightness(fgColor1));
centerX = (float)width / 2;
centerY = (float)height / 2;
// Modeled region is pie slice from 0 to angle
// Render things there and simultaneously render
// in the other regions
frameRate(30);
background(bgColor);
if(DEBUG) {
stroke(255,0,0);
line(centerX, centerY,
centerX + 200 * cos(0),
centerY + 200 * sin(0));
stroke(0,255,0);
line(centerX, centerY,
centerX + 200 * cos(divisionAngle),
centerY + 200 * sin(divisionAngle));
}
if(DEBUG) noLoop();
if(DEBUG) stroke(255);
}
void draw() {
for(int i = 0; i < loopsPerFrame; i++) {
// stroke(0, random(255), 0, random(127));
// color c = color(random(127,255), random(127), random(127), random(127));
// color c = color(random(255), random(255), 54, random(127));
color c = color(map(random(255), 0, 255, hue(fgColor1), hue(fgColor2)),
map(random(255), 0, 255, saturation(fgColor1), saturation(fgColor2)),
map(random(255), 0, 255, brightness(fgColor1), brightness(fgColor2)),
random(127));
stroke(c);
fill(c);
// EllipseKaleid(random(width), random(height), random(10,40), centerX, centerY);
strokeWeight(random(3, 10));
LineKaleid(random(width), random(height), random(width), random(height), centerX, centerY);
// strokeWeight(random(30));
// PointKaleid(random(width), random(height), centerX, centerY);
}
}
void mouseMoved()
{
// strokeWeight(30);
color c = color(random(255), random(255), 255, random(255));
stroke(c);
strokeWeight(1);
fill(c);
EllipseKaleid(mouseX, mouseY, random(10, 60), centerX, centerY);
}
float AngleOnUnitCircle(float x, float y, float cx, float cy) {
float tx = x - cx;
float ty = y - cy;
float angle = atan2(ty, tx);
// Compensating for atan2() returning a value
// between -PI and PI
if(angle < 0) {
angle = 2 * PI + angle;
}
return angle;
}
void BoxKaleid(float x, float y, float w, float h) {
}
/*
Attempting to do this in a simpler manner using the built-in
translate() and rotate() functions
void LineKaleid2(float x1, float y1, float x2, float y2, float cx, float cy) {
pushMatrix();
translate(cx, cy);
for(int i=0;i<radialDivisions;i++) {
if(DEBUG) println("i = " + i);
rotate((float)i * (2 * divisionAngle));
line(x1-cx, y1-cy, x2-cx, y2-cy);
// println("
// line(y1-cy, x1-cx, y2-cy, x2-cx);
}
popMatrix();
}
*/
void LineKaleid(float x1, float y1, float x2, float y2, float cx, float cy) {
float angle1, angle2;
float r1, r2;
float nx1, ny1, nx2, ny2;
// Finding radius and angle of first and second points in line
// x = r * cos(theta)
// y = r * sin(theta)
// With the angles of these points, we can add the divisionAngle,
// take the sine or cosine, and multiply by the radius to get
// the new x and y positions
r1 = sqrt(pow(x1 - cx, 2) + pow(y1 - cy, 2));
angle1 = AngleOnUnitCircle(x1, y1, cx, cy);
r2 = sqrt(pow(x2 - cx, 2) + pow(y2 - cy, 2));
angle2 = AngleOnUnitCircle(x2, y2, cx, cy);
if(DEBUG) println("Info on copied regions:");
if(DEBUG) println("r1 = " + r1);
if(DEBUG) println("angle1 = " + angle1);
if(DEBUG) println("r2 = " + r2);
if(DEBUG) println("angle2 = " + angle2);
// Render the line in each of the copied regions
for(int i = 0; i < radialDivisions; i++) {
float tempAngle1 = angle1 + (float)i * (2 * divisionAngle);
float tempAngle2 = angle2 + (float)i * (2 * divisionAngle);
nx1 = cx + r1 * cos(tempAngle1);
ny1 = cy + r1 * sin(tempAngle1);
nx2 = cx + r2 * cos(tempAngle2);
ny2 = cy + r2 * sin(tempAngle2);
line(nx1, ny1, nx2, ny2);
}
if(DEBUG) println("Info on mirrored regions:");
// For the mirrored region, the angles get mirrored obviously
angle1 = 2 * divisionAngle - angle1;
angle2 = 2 * divisionAngle - angle2;
if(DEBUG) println("r1 = " + r1);
if(DEBUG) println("angle1 = " + angle1);
if(DEBUG) println("r2 = " + r2);
if(DEBUG) println("angle2 = " + angle2);
// Render the line in each of the mirrored regions
for(int i = 0; i < radialDivisions; i++) {
float tempAngle1 = angle1 + (float)i * (2 * divisionAngle);
float tempAngle2 = angle2 + (float)i * (2 * divisionAngle);
nx1 = cx + r1 * cos(tempAngle1);
ny1 = cy + r1 * sin(tempAngle1);
nx2 = cx + r2 * cos(tempAngle2);
ny2 = cy + r2 * sin(tempAngle2);
line(nx1, ny1, nx2, ny2);
}
}
void PointKaleid(float x1, float y1, float cx, float cy) {
float angle1;
float r1;
float nx1, ny1;
// Finding radius and angle of first and second points in line
// x = r * cos(theta)
// y = r * sin(theta)
// With the angles of these points, we can add the divisionAngle,
// take the sine or cosine, and multiply by the radius to get
// the new x and y positions
r1 = sqrt(pow(x1 - cx, 2) + pow(y1 - cy, 2));
angle1 = AngleOnUnitCircle(x1, y1, cx, cy);
// Render the point in each of the copied regions
for(int i = 0; i < radialDivisions; i++) {
float tempAngle1 = angle1 + (float)i * (2 * divisionAngle);
nx1 = cx + r1 * cos(tempAngle1);
ny1 = cy + r1 * sin(tempAngle1);
point(nx1, ny1);
}
// For the mirrored region, the angle gets mirrored obviously
angle1 = 2 * divisionAngle - angle1;
// Render the point in each of the mirrored regions
for(int i = 0; i < radialDivisions; i++) {
float tempAngle1 = angle1 + (float)i * (2 * divisionAngle);
nx1 = cx + r1 * cos(tempAngle1);
ny1 = cy + r1 * sin(tempAngle1);
point(nx1, ny1);
}
}
// For now only handles circles, where w=h
// If w!=h, this will not properly handle the rotation of
// the ellipse
void EllipseKaleid(float x1, float y1, float w, float cx, float cy) {
float angle1;
float r1;
float nx1, ny1;
// Finding radius and angle of first and second points in line
// x = r * cos(theta)
// y = r * sin(theta)
// With the angles of these points, we can add the divisionAngle,
// take the sine or cosine, and multiply by the radius to get
// the new x and y positions
r1 = sqrt(pow(x1 - cx, 2) + pow(y1 - cy, 2));
angle1 = AngleOnUnitCircle(x1, y1, cx, cy);
// Render the point in each of the copied regions
for(int i = 0; i < radialDivisions; i++) {
float tempAngle1 = angle1 + (float)i * (2 * divisionAngle);
nx1 = cx + r1 * cos(tempAngle1);
ny1 = cy + r1 * sin(tempAngle1);
ellipse(nx1, ny1, w, w);
}
// For the mirrored region, the angle gets mirrored obviously
angle1 = 2 * divisionAngle - angle1;
// Render the point in each of the mirrored regions
for(int i = 0; i < radialDivisions; i++) {
float tempAngle1 = angle1 + (float)i * (2 * divisionAngle);
nx1 = cx + r1 * cos(tempAngle1);
ny1 = cy + r1 * sin(tempAngle1);
ellipse(nx1, ny1, w, w);
}
}