import processing.opengl.*; Point[] pointArray; int numPoints = 601;//must be divisible by 3, plus Bezier mainCurve; float animT = 0; int frame = 0; public void setup (){ background(0); smooth(); println("Setup"); size(800,500,OPENGL); createPoints(); } void createPoints(){ println("createPoints()"); pointArray = new Point[numPoints]; //compute first segment float angle = (float)Math.random()*TWO_PI; float maxDist = 1000; float dist = 500; pointArray[0] = new Point(width+20,height/2); pointArray[1] = new Point(pointArray[0].x+cos(angle-HALF_PI)*dist/2,pointArray[0].y+sin(angle-HALF_PI)*dist/2); float rand = (float)Math.random(); pointArray[2] = new Point(pointArray[0].x+cos(angle+HALF_PI)*dist*rand,pointArray[0].y+sin(angle+HALF_PI)*dist*rand); pointArray[3] = new Point(pointArray[0].x+cos(angle-HALF_PI)*dist*rand,pointArray[0].y+sin(angle-HALF_PI)*dist*rand); fill(0); ellipse(pointArray[0].x,pointArray[0].y,5,5); ellipse(pointArray[1].x,pointArray[1].y,5,5); ellipse(pointArray[2].x,pointArray[2].y,5,5); ellipse(pointArray[3].x,pointArray[3].y,5,5); //compute the rest of the segments for (int i=4;i mainCurve.maxT-animT){ animT = 0; } saveFrame("textCurves-"+nf(frame,4)+".tif"); frame +=1; } /* * This is the simple point datatype. There's probably something similar in Processing, but I wanted to be in control of everything. */ class Point{ float x; float y; Point (float x, float y){ this.x = x; this.y = y; } } /* * This is a bezier segment - this is set of 4 points, which make up: * * s0 - Endpoint 1 * s1 - control point 1 * s2 - control point 2 * s3 - Endpoint 2 * * All the intermediate points can be found via linear interpolation. */ class Segment{ Point s0; Point s1; Point s2; Point s3; Segment(Point s0, Point s1, Point s2, Point s3){ this.s0 = s0; this.s1 = s1; this.s2 = s2; this.s3 = s3; } } /* * Bezier class - creates a bezier curve from an array of points. */ class Bezier{ Point[] points; Segment[] segments; int maxT; Bezier(Point[] points) { this.points = points; parseSegments(); } private void parseSegments(){ this.segments = new Segment[((int)points.length/3) + 1]; println(this.segments.length); for (int i = 0; i< segments.length-1; i++){ int j=i*3; segments[i] = new Segment(points[j], points[j+1], points[j+2], points[j+3]); } maxT = segments.length-1; } /* * This returns a point on a bezier curve of n segments, from an input variable of t, which can be between 0 and n. * The method will automatically fetch the correct segment and give the exact value at t. Useful for complex curves. */ public Point pointOnBezier(float t) { if (t<0){ return new Point(-100,-100); } int seg = (int) Math.floor(t); Segment cp = segments[seg]; t -= seg; float ax, bx, cx; float ay, by, cy; float tSquared, tCubed; Point cPoint = new Point(0,0); /* calculate the polynomial coefficients */ cx = 3.0 * (cp.s1.x - cp.s0.x); bx = 3.0 * (cp.s2.x - cp.s1.x) - cx; ax = cp.s3.x - cp.s0.x - cx - bx; cy = 3.0 * (cp.s1.y - cp.s0.y); by = 3.0 * (cp.s2.y - cp.s1.y) - cy; ay = cp.s3.y - cp.s0.y - cy - by; /* calculate the curve point at parameter value t */ tSquared = t * t; tCubed = tSquared * t; cPoint.x = (ax * tCubed) + (bx * tSquared) + (cx * t) + cp.s0.x; cPoint.y = (ay * tCubed) + (by * tSquared) + (cy * t) + cp.s0.y; return cPoint; } }