/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.8CBmQLCilSm/rev.3198
*
* authors:
* Steven
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
// Steven de Brouwer <[email protected]>
// Still work in progress... the result is already awesome!
// Nice to be featured! Thank you!
//
// Feel free to copy, but:
// (C)redits 2016 Steven <[email protected]>
//
// Press Q to clear the canvas
int i = 0;
color lineColor = #707070;
float dtheta = 2*Math.PI * 3/360; // degrees
var Polygons = new Array();
boolean frist = true;
void deb(string tekst) { console.log(tekst); }
void drawPoly(p, c) {
var n = p.length>>1;
if (n<=1) {return;}
for(var i=0; i<n-1; i++)
{
stroke(c);
line(p[2*i+0],p[2*i+1],p[2*i+2],p[2*i+3]);
}
if (n>2) {
i=n-1;
line(p[2*i+0],p[2*i+1],p[0],p[1]);
}
stroke(lineColor);
}
void setup() {
size(500, 500);
smooth();
frameRate(5);
strokeWeight(1);
stroke(lineColor);
rectMode(CORNERS);
fill(0, 102, 153);
setUp();
}
void draw() { // this is run repeatedly.
if ( frist ) {
frist = false;
}
if ( mousePressed ){
var x = mouseX;
var y = mouseY;
found = -1;
for (i = 0; i < Polygons.length; i++) {
if (PolyK.ContainsPoint(Polygons[i], x, y)) {
found = i;
}
}
if (found >= 0) {
if (PolyK.GetArea(Polygons[found]) < 10000) { // 5000
fillPoly(found, x, y);
} else {
splitPoly(found, x, y);
}
}
}
}
void fillPoly(f, x, y) {
var poly = Polygons[f].slice();
//drawPoly(poly, #FF0000);
n = poly.length>>1
maxi=200;
var plusOrMinus = Math.random() < 0.5 ? -1 : 1;
plusOrMinus += n;
//deb("plusOrMinus = "+plusOrMinus );
var isc = PolyK.ClosestEdge(poly, x, y);
e1 = isc.edge;
while (n > 2 && maxi>0) {
e2 = (e1 + plusOrMinus ) % n;
//deb("e1="+e1+", e2="+e2);
e1 *= 2;
e2 *= 2;
theta = angle(poly[e1+0], poly[e1+1], poly[e2+0], poly[e2+1]);
dx = Math.cos(theta+dtheta); dy = Math.sin(theta+dtheta);
if ( ! PolyK.ContainsPoint(poly, poly[e1+0]+dx, poly[e1+1]+dy)) {
dx = Math.cos(theta-dtheta); dy = Math.sin(theta-dtheta);
}
//deb("dx="+dx+", dy="+dy+", theta="+theta);
ray = PolyK.Raycast(poly, poly[e1+0]+dx, poly[e1+1]+dy, dx, dy);
//if (ray == null || 2*ray.edge == e1) {
// dx = Math.cos(theta-dtheta); dy = Math.sin(theta-dtheta);
// ray = PolyK.Raycast(poly, poly[e1+0]+dx, poly[e1+1]+dy, dx, dy);
//}
if (ray == null) { return; }
// if (ray.edge == e2) {
line(poly[e1+0], poly[e1+1], poly[e1+0]+dx*ray.dist, poly[e1+1]+dy*ray.dist);
poly[e2+0] = poly[e1+0] + dx*ray.dist;
poly[e2+1] = poly[e1+1] + dy*ray.dist;
// }
maxi = maxi-1;
e1 = e1>>1;
e1 = (e1 + plusOrMinus ) % n;
//n = 0;
}
//drawPoly(poly, #00FF00);
}
void splitPoly(f, x, y) {
float r = random(-89, 89);
float a = tan(radians(r)); // y=ax+b
float b = y-(a*x);
xL= -5; yL=(a*xL) + b;
xR=width+5; yR=(a*xR) + b;
PolyDuo = PolyK.Slice( Polygons[f] , xL,yL , xR,yR );
Polygons.splice(found, 1, PolyDuo[0]);
Polygons.splice(found+1, 0, PolyDuo[1]);
drawPoly(PolyDuo[0], lineColor);
//drawPoly(Polygons[f], #00FF00);
//drawPoly(PolyDuo[1], lineColor);
}
void keyPressed() {
// deb("keyCode="+keyCode);
// q=81, c=67
if (keyCode == 81) { setUp(); } // clear canvas
}
void setUp() {
background(255);
Polygons = [];
polyscreen = [10,10, width-10,10, width-10,height-10, 10,height-10];
//drawPoly(polyscreen, #FF0F0F);
drawPoly(polyscreen, lineColor);
Polygons.push(polyscreen);
}
function angle(cx, cy, ex, ey) {
return Math.atan2(ey - cy, ex - cx); // range (-PI, PI]
//theta *= 180 / Math.PI; // rads to degs, range (-180, 180]
//if (theta < 0) theta = 360 + theta; // range [0, 360)
//return theta;
}