Smooth rendering of the line movement

Hello, I have been trying to make each compass line rotate smoothly, as per noise function value. However, no matter what I try, it moves like a second hand of the clock, rather than a smooth movement of rotation. Could you please point out what I am missing here?

Hello,

What you need to do is to draw some small steps in between your angle.

One way you can do that is to get a turning speed and for each loop rotate according to the speed and the elapsed time.

For example in this sketch, I set a desired angle every second, compute the speed needed to reach that new angle in 1 second and rotate my line at every loop just a little according to the ellapsed time.

var fromAngle, toAngle, currAngle;
var newAngleTimeThreshold, lastNewAngleTime;
var speed; // speed needed to turn from "fromAngle" to "toAngle" in "newAngleTimeThreshold"

function setup() {
  createCanvas(500, 500);
  
  // Init variables
  fromAngle = 0;
  toAngle = 0;
  currAngle = 0;
  
  newAngleTimeThreshold = 1000; // Get a new angle everysecond
  lastNewAngleTime = -1000; // To get a new angle on the first run
};

function draw() {
  background(20);
  
  // Get a new desired angle every second
  if (millis() - lastNewAngleTime > newAngleTimeThreshold) {
    fromAngle = currAngle;
    toAngle = random(TWO_PI);
    speed = (toAngle - fromAngle) / newAngleTimeThreshold;
    lastNewAngleTime = millis();
  }
  
  // Rotate according to the speed
  var deltaTime = millis() - lastNewAngleTime;
  currAngle = fromAngle + deltaTime * speed;
  
  // Draw the line to that angle
  stroke(200);
  push();
    translate(width / 2, height / 2);
    rotate(currAngle);
    line(0, 0, 0, 50);  
  pop();
};
1 Like

Based on @jb4x’s answer, I made a shorter sketch that uses (Perlin-)noise() directly and thus doesn’t need any speed variables and update events.

let currAngle;

function setup() {
  createCanvas(500, 500);
  
  // Init variables
  currAngle = 0;
  stroke(200);
};

function draw() {
  background(20);
  
  // One-dimensional (just for the angle!) Perlin noise.
  currAngle = noise(millis()/2500) * TWO_PI

  // Extend range of Perlin noise
  currAngle = currAngle * 4
  
  // Draw the line to that angle
  push();
    translate(width / 2, height / 2);
    rotate(currAngle);
    line(0, 0, 0, 50);  
  pop();
};

Note that I multiplied (mapped) the output of the Perlin noise() to a range that is larger than [0, TWO_PI] (which in theory would be enough to get the full circle). This is because Perlin noise rarely (if ever?) takes on values that are close to the theoretical limits of 0 and 1, but rather between 0.25 and 0.75, “spending most of its time” around ~0.5.

1 Like