Hi,
I’m trying to adapt the code which has been written in java by Daniel Shiffman on his youtube channel into P5.js and I’ve met some problems. The loop which I used to draw the shape doesn’t work properly. In object which I created a vector values x,y and z are still 0 ( 0: Vector {vx: 0, vy: 0, vz: 0}
1: Vector {vx: 0, vy: 0, vz: 0} etc. etc). Where am I wrong?
This is a video which I mentioned → https://www.youtube.com/watch?v=r6YMKr1X0VA&t=104s
This is my code:
let beta;
let arr =[];
function setup() {
createCanvas(400, 400, WEBGL);
}
function draw(){
beta = 0;
background(0);
translate(width/2, height/2);
let r = 250*(0.8 * 1.6 * sin(6 * beta));
let theta = 2 * beta;
let phi = 0.6 * PI * sin(12 * beta);
let x = r * cos(phi) * cos(theta);
let y = r * cos(phi) * sin(theta);
let z = r * sin(phi);
arr.push(new Vector(x,y,z));
beta += 0.01;
stroke(255);
strokeWeight(3);
noFill();
beginShape();
for(let v of arr) {
vertex(v.vx, v.vy, v.vz);
}
endShape();
}
class Vector {
constructor(vx, vy, vz) {
this.vx = vx;
this.vy = vy;
this.vz = vz;
}
}
1 Like
greg500:
Where am I wrong?
Even though Java & JS share most of their syntaxes, there are still some important differences.
A peculiar 1 of them is which default value is assigned to a newly created variable or property.
Java assigns a different initial value to a newly field depending on its declared datatype:
But not JS (Python the same)! Default value is always undefined
(None
to Python).
So just after let beta;
, variable beta is equal to undefined
.
And any math operations w/ undefined
result NaN
!
2 Likes
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;
}
}
1 Like
And while I was at it, I did a Python Mode version too:
“Knot3D.pyde”:
"""
* 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/4
"""
"""
* http://PaulBourke.net/geometry/knots/
* Knot 4 (1992/Oct):
*
* r(beta) = 0.8 + 1.6 * sin(6 * beta)
* theta(beta) = 2 * beta
* phi(beta) = 0.6 * pi * sin(12 * beta)
*
* x = r * cos(phi) * cos(theta)
* y = r * cos(phi) * sin(theta)
* z = r * sin(phi)
"""
ANGLE_STEP, BETA_STEP = .02, .01
MAG, SEGS_LIMIT = 100.0, PI + BETA_STEP
PI_DOT_6 = PI * .6
angle = beta = 0.0
paused = False
knots = []
def setup():
size(600, 600, P3D)
smooth(8)
colorMode(HSB)
noFill()
strokeWeight(8.0)
def draw():
global angle, beta
background(0)
translate(width>>1, height>>1)
rotateY(angle)
angle += ANGLE_STEP
beta <= SEGS_LIMIT and addKnot()
beta += BETA_STEP
with beginShape():
for k in knots:
stroke(k.c)
vertex(k.v.x, k.v.y, k.v.z)
def mousePressed():
global paused
paused ^= True
noLoop() if paused else loop()
def keyPressed(): mousePressed()
def addKnot():
r = MAG * (.8 + 1.6 * sin(6 * beta))
theta = 2 * beta
phi = PI_DOT_6 * sin(12 * beta)
rCosPhi = r * cos(phi)
x = rCosPhi * cos(theta)
y = rCosPhi * sin(theta)
z = r * sin(phi)
knot = Knot(x, y, z)
knots.append(knot)
print '%d: %s' % (len(knots), knot)
class Knot:
def __init__(k, *vec):
k.v = vec[0] if len(vec) is 1 else PVector(*vec)
k.c = color(k.v.mag(), 255, 255)
def __str__(k): return 'Vec: %s \tHSB: %d' % (k.v, k.c)
3 Likes
And finally the “3D Knot” p5js version. Watch it online below:
OpenProcessing.org/sketch/608726
However, there’s a worse bug in it: the last stroke() determines the color for all vertex() !
“index.html”:
<!DOCTYPE html>
<meta charset=utf-8>
<meta name=viewport content=width=device-width,initial-scale=1>
<script async src=https://cdn.JsDelivr.net/npm/p5/lib/p5.js></script>
<script defer src=sketch.js></script>
“sketch.js”:
/**
* 3D Knot (2017/Dec)
* Daniel Shiffman
* https://YouTu.be/r6YMKr1X0VA
*
* Mod GoToLoop (v1.0.1) (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/5
*/
/**
* http://PaulBourke.net/geometry/knots/
* Knot 4 (1992/Oct):
*
* r(beta) = 0.8 + 1.6 * sin(6 * beta)
* theta(beta) = 2 * beta
* phi(beta) = 0.6 * pi * sin(12 * beta)
*
* x = r * cos(phi) * cos(theta)
* y = r * cos(phi) * sin(theta)
* z = r * sin(phi)
*/
"use strict";
const π = Math.PI, ANGLE_STEP = .02, BETA_STEP = .01,
MAG = 100.0, SEGS_LIMIT = π + BETA_STEP,
PI_DOT_6 = π*.6,
knots = []
let α = 0.0, β = 0.0, paused = false, bg
function setup() {
createCanvas(600, 600, WEBGL).mousePressed(togglePause)
bg = color(0)
colorMode(HSB).strokeWeight(8.0).noFill()
}
function draw() {
background(bg).rotateY(α += ANGLE_STEP)
β <= SEGS_LIMIT && addKnot()
β += BETA_STEP
beginShape()
for (const { c, v } of knots) stroke(c).vertex(v.x, v.y, v.z)
endShape()
}
function togglePause() {
(paused = !paused)? noLoop() : loop()
}
function keyPressed() {
togglePause()
}
function addKnot() {
const r = MAG * (.8 + sin(6*β)*1.6),
θ = 2*β, φ = PI_DOT_6 * sin(12*β),
rCosφ = r * cos(φ),
x = rCosφ * cos(θ), y = rCosφ * sin(θ), z = r * sin(φ),
knot = new Knot(x, y, z)
knots.push(knot)
console.log(knots.length + ':', knot)
}
class Knot {
constructor(...vec) {
this.v = vec.length === 1? vec[0] : createVector(...vec)
this.c = color(this.v.mag(), 100, 100)
}
}
2 Likes
greg500
October 17, 2018, 10:38am
6
Thanks. This is exactly what I am looking for.