# Vertex, loop and draw along a vertex path

**URL:** <https://discourse.processing.org/t/vertex-loop-and-draw-along-a-vertex-path/4545>\
**Category:** Coding Questions\
**Created:** [October 16, 2018, 7:08pm UTC](https://discourse.processing.org/t/vertex-loop-and-draw-along-a-vertex-path/4545 "2018-10-16T19:08:15Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![greg500](https://avatars.discourse-cdn.com/v4/letter/g/ed655f/32.png) [@greg500](https://discourse.processing.org/u/greg500)\
**Post date:** [October 16, 2018, 7:08pm UTC](https://discourse.processing.org/t/vertex-loop-and-draw-along-a-vertex-path/4545/1 "2018-10-16T19:08:15Z")

</div>

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](https://www.youtube.com/watch?v=r6YMKr1X0VA&t=104s)

This is my code:

```auto
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;
      }
}

```

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [October 17, 2018, 4:35am UTC](https://discourse.processing.org/t/vertex-loop-and-draw-along-a-vertex-path/4545/2 "2018-10-17T04:35:29Z")

</div>

> [@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:

> **[Primitive Data Types (The Java™ Tutorials \>        
            Learning...](https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html)**
>
> This beginner Java tutorial describes fundamentals of programming in the Java programming language

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`!

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [October 17, 2018, 4:42am UTC](https://discourse.processing.org/t/vertex-loop-and-draw-along-a-vertex-path/4545/3 "2018-10-17T04:42:33Z")

</div>

I did some refactoring to the original Java Mode version. ☕  
You can watch it running online here: 🏃‍♂️

[OpenProcessing.org/sketch/608725](http://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”:

```java
/**
 * 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;
  }
}

```

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [October 17, 2018, 4:46am UTC](https://discourse.processing.org/t/vertex-loop-and-draw-along-a-vertex-path/4545/4 "2018-10-17T04:46:13Z")

</div>

And while I was at it, I did a Python Mode version too: 🐍

## “Knot3D.pyde”:

```python
"""
 * 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)

```

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [October 17, 2018, 4:52am UTC](https://discourse.processing.org/t/vertex-loop-and-draw-along-a-vertex-path/4545/5 "2018-10-17T04:52:50Z")

</div>

And finally the “3D Knot” p5js version. Watch it online below: 😁  
[OpenProcessing.org/sketch/608726](http://OpenProcessing.org/sketch/608726)

However, there’s a worse bug in it: the last **stroke()** determines the color for all **vertex()**! 👎

## “index.html”:

```auto
<!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”:

```javascript
/**
 * 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)
  }
}

```

---

<div class="post-metadata">

**Author:** ![greg500](https://avatars.discourse-cdn.com/v4/letter/g/ed655f/32.png) [@greg500](https://discourse.processing.org/u/greg500)\
**Post date:** [October 17, 2018, 10:38am UTC](https://discourse.processing.org/t/vertex-loop-and-draw-along-a-vertex-path/4545/6 "2018-10-17T10:38:46Z")

</div>

Thanks. This is exactly what I am looking for.
