如何生成连续的色彩艺术化 Perlin 流场

7

我试图实现如下图所示的效果:

picture

我使用了p5.js库,但我不是一名图形程序员,因此很难实现这种特定的图形效果。我向你分享我的代码,同时我也遵循了这个教程

Index.html

    <html>
    <head>
        <script language="javascript" type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.min.js"></script>
        <script language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/addons/p5.dom.min.js"></script>
        <script language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/addons/p5.sound.min.js"></script>
        <script language="javascript" type="text/javascript" src="sketch.js"></script>
        <script language="javascript" type="text/javascript" src="particle.js"></script>
    </head>
<body>
</body>
</html>

particle.js

  function Particle() {
  this.pos = createVector(random(width), random(height));
  this.vel = createVector(0, 0);
  this.acc = createVector(0, 0);
  this.maxspeed = 4;
  this.h = 0;
this.alphaPower = 20;
  this.prevPos = this.pos.copy();

  this.update = function() {
    this.vel.add(this.acc);
    this.vel.limit(this.maxspeed);
    this.pos.add(this.vel);
    this.acc.mult(0);
  }

  this.follow = function(vectors) {
    var x = floor(this.pos.x / scl);
    var y = floor(this.pos.y / scl);
    var index = x + y * cols;
    var force = vectors[index];
    this.applyForce(force);
  }

  this.applyForce = function(force) {
    this.acc.add(force);
  }

  this.showBlue = function() {
    stroke(0, 76, 153, this.alphaPower);
    
    strokeWeight(1);
    line(this.pos.x, this.pos.y, this.prevPos.x, this.prevPos.y);
   
    this.updatePrev();
  }

  this.showMaroon = function() {
    stroke(165, 0, 68, this.alphaPower); // maroon
   
    strokeWeight(1);
    line(this.pos.x, this.pos.y, this.prevPos.x, this.prevPos.y);
     
    this.updatePrev();
  }

  this.showYellow = function() {
    stroke(237, 188, 0, this.alphaPower);
    //stroke(1,2);
    
    strokeWeight(1);
    line(this.pos.x, this.pos.y, this.prevPos.x, this.prevPos.y);
    
    this.updatePrev();
  }


  this.updatePrev = function() {
    this.prevPos.x = this.pos.x;
    this.prevPos.y = this.pos.y;
  }

  this.edges = function() {
    if (this.pos.x > width) {
      this.pos.x = 0;
      this.updatePrev();
    }
    if (this.pos.x < 0) {
      this.pos.x = width;
      this.updatePrev();
    }
    if (this.pos.y > height) {
      this.pos.y = 0;
      this.updatePrev();
    }
    if (this.pos.y < 0) {
      this.pos.y = height;
      this.updatePrev();
    }

  }

}

sketch.js

var inc = 0.01;
var scl = 10;
var cols, rows;

var zoff = 0;

var fr;

var particles = [];
var particlesMaroon = [];
var particlesBlue = [];
var particlesYellow = [];

var flowfield;
var flowfieldMaroon;
var flowfieldBlue;
var flowfieldYellow;

var gamma_is_high = false;
var beta_is_high = false;
var alpha_is_high = false;

var maroon_data=1000;
var blue_data = 1000;
var yellow_data = 1000;

setInterval(function() {
    ChangeLines();
}, 5000);

function dataRequest(){
    socket.emit('datarequest', {data: "request"});
}

function ChangeLines(){

    maroon_data = random(500, 2000);
    blue_data = random(500, 2000);
    yellow_data = random(500, 2000);

    gamma_is_high = true;
    alpha_is_high = true;
    beta_is_high = true;
}

function setup() {
  slider = createSlider(0.01, 0.1, 0.02,0);
  slider.position(10, 10);
  slider.style('width', '80px');
  ChangeLines();
  createCanvas(windowWidth-15, windowHeight-20);
  cols = floor(width / scl);
  rows = floor(height / scl);
  fr = createP('');

  flowfield = new Array(cols * rows);
  flowfieldMaroon = new Array(cols * rows);
  flowfieldBlue = new Array(cols * rows);
  flowfieldYellow = new Array(cols * rows);

  for (var i = 0; i < 1000; i++) {
    particles[i] = new Particle();
    particlesMaroon[i] = new Particle();
    particlesBlue[i] = new Particle();
    particlesYellow[i] = new Particle();
  }
  background(255);
}


function draw() {
  
  let val = slider.value();
  inc = val;

  var yoff = 0;
  for (var y = 0; y < rows; y++) {
    var xoff = 0;
    for (var x = 0; x < cols; x++) {
      var index = x + y * cols;
      var angle = noise(xoff, yoff, zoff) * TWO_PI;
      var angleMaroon = noise(xoff, yoff, zoff) * TWO_PI;
      var angleBlue = noise(xoff, yoff, zoff) * TWO_PI;
      var angleYellow = noise(xoff, yoff, zoff) * TWO_PI;

      var v = p5.Vector.fromAngle(angle);
      var vm = p5.Vector.fromAngle(angleMaroon);
      var vb = p5.Vector.fromAngle(angleBlue);
      var vy = p5.Vector.fromAngle(angleYellow);

      v.setMag(5);
      vm.setMag(5);
      vb.setMag(5);
      vy.setMag(5);

      flowfield[index] = v;
      flowfieldMaroon[index] = vm;
      flowfieldBlue[index] = vb;
      flowfieldYellow[index] = vy;
      xoff += inc;
     
    }
    yoff += inc;

    
  }
  zoff += 0.0003;
  for (var i = 0; i < particles.length; i++) {
   
    if(gamma_is_high==true){
        particlesMaroon[i].follow(flowfieldMaroon);
        particlesMaroon[i].update();
        particlesMaroon[i].edges();
        particlesMaroon[i].showMaroon();
    }
    

    if(beta_is_high){
        particlesBlue[i].follow(flowfieldBlue);
        particlesBlue[i].update();
        particlesBlue[i].edges();
        particlesBlue[i].showBlue();
    }
   
    if(alpha_is_high){
        particlesYellow[i].follow(flowfieldYellow);
        particlesYellow[i].update();
        particlesYellow[i].edges();
        particlesYellow[i].showYellow();
    }
    
  }

  fr.html(floor(frameRate()));
}

变量maroon_datablue_datayellow_data是来自EEG设备的数据,稍后将进行计算,但目前仅为原型硬编码值。布尔变量gamma_is_highbeta_is_highalpha_is_high目前设置为true。但我只能达到以下所示的程度:

enter image description here

实际输出如下图所示:

the art of feeling

请帮助我获得这个实际的输出。感谢您的帮助。

也许可以尝试使用示例中提供的角度 noise(xoff, yoff, zoff) * TWO_PI * 4?示例链接:https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/CodingTrain/website/tree/master/CodingChallenges/CC_024_PerlinNoiseFlowField/P5 - shrys
我已经试过了,它只是改变了模式,这不是我想要的。对我没有用。 - Saad Anees
请帮我获取实际输出,您是指期望的输出吗?实际输出是您当前拥有的失败内容,期望输出是您想要的正确内容。 - ggorlen
1个回答

0

我曾经做过这样的事情。我只有一个粒子数组,只是通过一个小的随机量来改变它们的 RGB 值。我使用了一个对象来存储颜色值。

function setup() {
  //Do all the normal stuff
  var c = {r: 100, g:100, b:100)
}
function draw() {
  //All the other stuff
  c.r += random(-3,3);
  c.g += random(-3,3);
  c.b += random(-3,3);
}

然后在粒子中:

show() {
   fill(c.r,c.g,c.b, whateverAlphaYouWant);
   //Do all the rest
}

您可以随时调整数值以获得所需的任何颜色。


哇,你来得太晚了 :D 但我会尝试的。谢谢。 - Saad Anees

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接