使用函数或 类 创建多个素数螺旋

using functions or classes to create multiple prime spirals

在 Dan Shiffman 的编码挑战中获得灵感后,我正在尝试创建几个素数螺旋:https://www.youtube.com/watch?v=a35KWEjRvc0&t=716s&ab_channel=TheCodingTrain

我希望螺旋线相互重叠,颜色不同,质数序列的起点有偏移,使每个螺旋线具有不同的外观。 我很想使用 OOP 来解决这个问题,但我什至不能让它与函数一起工作,只有 绘制了其中一个螺旋线。

我认为它可能与 noLoop 函数有关,但删除它没有帮助。

如果您喜欢这个主题,我真的可以推荐这个数字爱好者视频,深入探讨素数:

// https://thecodingtrain.com/CodingChallenges/167-prime-spiral.html
// https://youtu.be/a35KWEjRvc0

let x, y;
let step = 1;
let stepSize = 20;
let numSteps = 1;
let state = 0;
let turnCounter = 1;
let totalSteps;
let offset = 0;

function isPrime(value) {
  if (value == 1) return false;
  for (let i = 2; i <= sqrt(value); i++) {
    if (value % i == 0) {
      return false;
    }
  }
  return true;
}

function setup() {
  createCanvas(500, 500);

  const cols = width / stepSize;
  const rows = height / stepSize;
  totalSteps = cols * rows;

  x = width / 2;
  y = height / 2;
  background(0);
}

function draw() {

  primeSpiral(20, 1)
  primeSpiral(30, 200)
  noStroke();
}


function primeSpiral(offset, color){
  if (!isPrime(step+offset)) {
    //might put something here

  } else {
    let r = stepSize * 0.5;
    fill(color, 99, 164);
    push();
    translate(x, y);
    rotate(-PI / 4);
    triangle(-r, +r, 0, -r, +r, +r);
    pop();
  }

  switch (state) {
    case 0:
      x += stepSize;
      break;
    case 1:
      y -= stepSize;
      break;
    case 2:
      x -= stepSize;
      break;
    case 3:
      y += stepSize;
      break;
  }

  if (step % numSteps == 0) {
    state = (state + 1) % 4;
    turnCounter++;
    if (turnCounter % 2 == 0) {
      numSteps++;
    }
  }
  step++;

  if (step > totalSteps) {
    noLoop();
  }
}

你的问题是大多数变量只有在两个主螺旋都有机会画出三角形时才应该改变。

"step" 从 1 开始。第一个螺旋检查是否应使用 "step" 值为 1 绘制三角形。然后 "step" 增加 1,其他变量如 "x" 和 " y" 相应地改变。然后第二个螺旋检查它是否应该绘制一个“步长”值为 2 的三角形。

因为每次调用 primeSpiral() 函数时都会递增“step”,所以在 draw() 函数的每个循环中对 primeSpiral() 的第二次调用将始终具有偶数的“step”值。由于第二次调用 primeSpiral() 的“偏移”值也是偶数,step+offset 将始终为偶数,因此永远不会是质数。

要解决此问题,您必须每帧仅更改一次“步长”。我已经编辑了您的代码来解决这个问题。

// https://thecodingtrain.com/CodingChallenges/167-prime-spiral.html
// https://youtu.be/a35KWEjRvc0

let x, y;
let step = 1;
let stepSize = 20;
let numSteps = 1;
let state = 0;
let turnCounter = 1;
let totalSteps;
let offset = 0;

function isPrime(value) {
  if (value == 1) return false;
  for (let i = 2; i <= sqrt(value); i++) {
    if (value % i == 0) {
      return false;
    }
  }
  return true;
}

function setup() {
  createCanvas(500, 500);

  const cols = width / stepSize;
  const rows = height / stepSize;
  totalSteps = cols * rows;

  x = width / 2;
  y = height / 2;
  background(0);
}

function draw() {

  primeSpiral(20, 1)
  primeSpiral(30, 200)
  
  incrementStep();
  
  noStroke();
}

function incrementStep()
{
  switch (state) {
    case 0:
      x += stepSize;
      break;
    case 1:
      y -= stepSize;
      break;
    case 2:
      x -= stepSize;
      break;
    case 3:
      y += stepSize;
      break;
  }

  if (step % numSteps == 0) {
    state = (state + 1) % 4;
    turnCounter++;
    if (turnCounter % 2 == 0) {
      numSteps++;
    }
  }
  step++;

  if (step > totalSteps) {
    noLoop();
  }
}

function primeSpiral(offset, color){
  if (!isPrime(step+offset)) {
    //might put something here

  } else {
    let r = stepSize * 0.5;
    fill(color, 99, 164);
    push();
    translate(x, y);
    rotate(-PI / 4);
    triangle(-r, +r, 0, -r, +r, +r);
    pop();
  }


}

我所做的唯一更改是从 primeSpiral() 函数中删除所有涉及更改变量值(例如“step”、“x”和“y”)的代码,并将其移至称为 incrementStep() 的单独函数。此函数每帧调用一次,在两次调用 primeSpiral() 之后。