/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.d0ISMlrvCzv/rev.1783
*
* authors:
* hansi raber
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
// Distance-parametrized Catmul-Rom curves.
// use alpha=0.5 (key 's') for the prettiest curves.
// Press q/w to change curve parameter (0...1)
// a,s,d are special values (resp. 0.0, 0.5, 1.0)
// Press space for new random points
int N = 6;
float points[][] = new float[N][2];
float alpha = 0.5;
void setup(){
size( 500, 500 );
randomize();
}
void randomize(){
for( int i = 0; i < N; i++ ){
points[i][0] = random( 10, width-20 );
points[i][1] = random( 10, height-20 );
}
}
void draw(){
background( 255 );
fill( 0 );
noStroke();
for( int i = 0; i < N; i++ ){
ellipse( points[i][0], points[i][1], 5, 5 );
}
stroke( 0 );
noFill();
cmrCurve( points, alpha, false );
}
void cmrCurve( float[] points[], float alpha, boolean close ){
int N = points.length;
for( int i = 0; i < N - 3; i++ ){
cmrSegment( points[i+0], points[i+1], points[i+2], points[i+3], alpha );
}
if( close && N >= 3 ){
cmrSegment( points[N-3], points[N-2], points[N-1], points[0], alpha );
cmrSegment( points[N-2], points[N-1], points[0], points[1], alpha );
cmrSegment( points[N-1], points[0], points[1], points[2], alpha );
}
}
void cmrSegment( float p0[], float p1[], float p2[], float p3[], alpha ){
float d1 = dist( p0[0], p0[1], p1[0], p1[1] );
float d2 = dist( p1[0], p1[1], p2[0], p2[1] );
float d3 = dist( p2[0], p2[1], p3[0], p3[1] );
bezier(
p1[0],
p1[1],
(pow(d1, 2*alpha)*p2[0]-pow(d2, 2*alpha)*p0[0] + (2 * pow(d1, 2*alpha) + 3*pow(d1*d2, alpha) + pow(d2, 2*alpha))*p1[0]) / (3*pow(d1,alpha)*(pow(d1,alpha)+pow(d2,alpha))),
(pow(d1, 2*alpha)*p2[1]-pow(d2, 2*alpha)*p0[1] + (2 * pow(d1, 2*alpha) + 3*pow(d1*d2, alpha) + pow(d2, 2*alpha))*p1[1]) / (3*pow(d1,alpha)*(pow(d1,alpha)+pow(d2,alpha))),
(pow(d3, 2*alpha)*p1[0]-pow(d2, 2*alpha)*p3[0] + (2 * pow(d3, 2*alpha) + 3*pow(d2*d3, alpha) + pow(d2, 2*alpha))*p2[0]) / (3*pow(d3,alpha)*(pow(d3,alpha)+pow(d2,alpha))),
(pow(d3, 2*alpha)*p1[1]-pow(d2, 2*alpha)*p3[1] + (2 * pow(d3, 2*alpha) + 3*pow(d2*d3, alpha) + pow(d2, 2*alpha))*p2[1]) / (3*pow(d3,alpha)*(pow(d3,alpha)+pow(d2,alpha))),
p2[0],
p2[1]
);
}
void keyPressed(){
var str = "" + String.fromCharCode( parseInt(key) );
if( str == "q" ) alpha += 0.1;
if( str == "w" ) alpha -= 0.1;
if( str == "a" ) alpha = 0.0;
if( str == "s" ) alpha = 0.5;
if( str == "d" ) alpha = 1.0;
if( str == " " ) randomize();
alpha = constrain( alpha, 0.0, 1.0 );
}