Skip to content

Instantly share code, notes, and snippets.

@yangsu
Created April 6, 2012 18:47
Show Gist options
  • Save yangsu/2322026 to your computer and use it in GitHub Desktop.
Save yangsu/2322026 to your computer and use it in GitHub Desktop.
Curve Following demo for Processing
/*
Simple Curve following code
Use mouse to draw a curve, then an ellipse will animate by following the curve
Controls
= to increase the speed
- to decrease the speed
s to show points
*/
// original points as drawn by the user
List<PVector> curvePoints = new ArrayList<PVector>();
boolean isAnimating = false;
// current interpolation time
float t = 0;
// Index of the current segment used for interpolation
int index = 0;
float speed = 2.5;
boolean showPoints = false;
void setup() {
size(800, 800);
strokeWeight(4);
ellipseMode(CENTER);
smooth();
}
void draw() {
background(150);
noFill();
if (isAnimating) {
stroke(200, 0 ,0);
beginShape();
for (PVector p : curvePoints) {
if (showPoints) ellipse(p.x, p.y, 5, 5);
curveVertex(p.x, p.y);
}
endShape();
stroke(0, 200, 0);
PVector a = curvePoints.get(index);
PVector b = curvePoints.get(index + 1);
PVector c = curvePoints.get(index + 2);
PVector d = curvePoints.get(index + 3);
float x = curvePoint(a.x, b.x, c.x, d.x, t);
float y = curvePoint(a.y, b.y, c.y, d.y, t);
ellipse(x, y, 20, 20);
update(b, c);
}
else {
stroke(0);
for (PVector p : curvePoints) {
point(p.x, p.y);
}
}
}
void update (PVector start, PVector end) {
// note: use linear distance as an approximation
t += speed / PVector.dist(start, end);
if (t >= 1.0) {
// Move on to the next segment and reset time
t = 0;
index++;
// Reached the end of the curve
if (index > curvePoints.size() - 4) {
index = 0;
}
}
}
void mousePressed() {
curvePoints.clear();
curvePoints.add(new PVector(mouseX, mouseY));
isAnimating = false;
}
void mouseDragged() {
curvePoints.add(new PVector(mouseX, mouseY));
}
void mouseReleased() {
curvePoints.add(new PVector(mouseX, mouseY));
if (curvePoints.size() >= 4) {
isAnimating = true;
t = 0;
index = 0;
}
else {
curvePoints.clear();
}
}
void keyPressed() {
if (key == '-') {
speed = max(0, speed - 0.2);
}
else if (key == '=') {
speed += 0.2;
}
else if (key == 's') {
showPoints = !showPoints;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment