I did some refactoring to the original Java Mode version.
You can watch it running online here:
OpenProcessing.org/sketch/608725
The online version got a bug though: strokeWeight() is completely ignored by vertex()!
But it runs 100% correctly in the PDE (Processing’s IDE) though.
“Knot3D.pde”:
/**
* 3D Knot (2017/Dec)
* Daniel Shiffman
* https://YouTu.be/r6YMKr1X0VA
*
* Mod GoToLoop (v1.0.3) (2018/Oct/16)
* https://OpenProcessing.org/sketch/608725 (pjs)
* https://OpenProcessing.org/sketch/608726 (p5js)
*
* https://Discourse.Processing.org/t/
* vertex-loop-and-draw-along-a-vertex-path/4545/3
*/
/**
* http://PaulBourke.net/geometry/knots/
* Knot 4 (1992/Oct):
*
* r(beta) = 0.8 + 1.6 * sin(6.0 * beta)
* theta(beta) = 2 * beta
* phi(beta) = 0.6 * pi * sin(12.0 * beta)
*
* x = r * cos(phi) * cos(theta)
* y = r * cos(phi) * sin(theta)
* z = r * sin(phi)
*/
import java.util.List;
final List<Knot> knots = new ArrayList<Knot>();
static final float
ANGLE_STEP = .02, BETA_STEP = .01,
MAG = 100.0, SEGS_LIMIT = PI + BETA_STEP,
PI_DOT_6 = PI * .6;
float angle, beta;
boolean paused;
void setup() {
size(600, 600, P3D);
smooth(8);
colorMode(HSB);
noFill();
strokeWeight(8.0);
}
void draw() {
background(0);
translate(width>>1, height>>1);
rotateY(angle += ANGLE_STEP);
if (beta <= SEGS_LIMIT) addKnot();
beta += BETA_STEP;
beginShape();
for (final Knot k : knots) {
stroke(k.c);
vertex(k.v.x, k.v.y, k.v.z);
}
endShape();
}
void mousePressed() {
if (paused ^= true) noLoop();
else loop();
}
void keyPressed() {
mousePressed();
}
void addKnot() {
final float
r = MAG * (.8 + 1.6 * sin(6.0 * beta)),
theta = 2.0 * beta,
phi = PI_DOT_6 * sin(12.0 * beta),
rCosPhi = r * cos(phi),
x = rCosPhi * cos(theta),
y = rCosPhi * sin(theta),
z = r * sin(phi);
final Knot knot = new Knot(x, y, z);
knots.add(knot);
println(knots.size() + ": " + knot);
}
class Knot {
final PVector v;
final color c;
Knot(final float x, final float y, final float z) {
this(new PVector(x, y, z));
}
Knot(final PVector vec) {
c = color((v = vec).mag(), 255, 255);
}
String toString() {
return "Vec: " + v + " \tHSB: " + c;
}
}