Anton E
Anton E

Reputation: 81

Drawing an irregular circle with an array of points

I'm trying to draw an irregular circles that animates for the first n number of frames in a sketch. What I want is to generate points and then to draw a line from the current point to the previous one, but am getting an error.

function irregularCircle(limit) {
  let points = []
  let t = frameCount / 20
  let i = floor(t)
  if (frameCount < limit) {
    let radius = w(.25)
    let x = width/2 + radius*cos(t)*noise(t/2)
    let y = height/2 + radius*sin(t)*noise(t/2)
    let point = createVector(x,y)
    points.push(point)
    let pt = points[i]
    let old_pt = points[i-1]
    stroke(24,34,64,75)
    strokeWeight(w(.001))
    if (frameCount > 1 && frameCount < limit) {
      line(pt.x,pt.y,old_pt.x,old_pt.y)
    }
  }
}

I get "Uncaught TypeError: Cannot read properties of undefined (reading 'x')" in response. What am I doing wrong?

EDIT: no longer getting the error, but still not drawing a circle.

Thanks in advance.

Upvotes: 2

Views: 293

Answers (1)

George Profenza
George Profenza

Reputation: 51837

@danh si right about i-1.

Additionally there another error: let points = []; should probably be global, otherwise the list gets reset with each call.

It's unclear what the w() function does, but you should double check the values returned are valid.

Here's a tweaked version of your code with the above notes applied:

let points = [];
  
function setup() {
  createCanvas(300, 300);
}

function draw() {
  irregularCircle(3200);
}

function irregularCircle(limit) {
  let t = frameCount / 20
  let i = floor(t)
  if (frameCount < limit) {
    let radius = 250;
    let x = width/2 + radius*cos(t)*noise(t/2)
    let y = height/2 + radius*sin(t)*noise(t/2)
    let point = createVector(x,y)
    points.push(point)
    let pt = points[i]
    let old_pt = points[i > 0 ? i-1 : 0]
    stroke(24,34,64,75)
    strokeWeight(0.1);
    if (frameCount > 1 && frameCount < limit) {
      line(pt.x,pt.y,old_pt.x,old_pt.y)
    }
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.min.js"></script>

Since you're connecting the previous point to the current point, you might not need to keep appending points to a list: you can simply hold a reference to the previous point instead:

let oldPt;
  
function setup() {
  createCanvas(300, 300);
}

function draw() {
  irregularCircle(3200);
}

function irregularCircle(limit) {
  let t = frameCount / 20
  let i = floor(t)
  if (frameCount < limit) {
    let radius = 250;
    let x = width/2 + radius*cos(t)*noise(t/2)
    let y = height/2 + radius*sin(t)*noise(t/2)
    let pt = createVector(x,y)
    // check if the previous point exists before drawing a line
    if(oldPt){
      if (frameCount > 1 && frameCount < limit) {
        line(pt.x,pt.y,oldPt.x,oldPt.y)
      }
    }
    // now that we've drawn the line we can point the old point to the current point
    oldPt = pt;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.min.js"></script>

Upvotes: 2

Related Questions