P5.js上每个点都有经典箭头的静态向量场

Static vector field with classic arrows at every point on p5.js(P5.js上每个点都有经典箭头的静态向量场)
本文介绍了P5.js上每个点都有经典箭头的静态向量场的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目标是使用p5.js在2D或3D网格上的每个点上显示一个带有箭头的矢量场(即尖端带有人字形的线段)。原因是我看到了很多创造性的艺术使用它,而流场(?)看起来很酷,那么为什么不用它们来描述有或没有运动的物理矢量场。

我对p5.js一无所知,但快速的在线搜索显示,我可以生成从左上角开始的位置向量,以及将原点连接到其终点或从一个位置向量到另一个位置向量的线(段):

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

function draw() {
  background(0);
  
  let vec1 = createVector(100,100);
  let vec2 = createVector(30,150);
  

    //First vector
      strokeWeight(10);
      stroke(250,250,250);
      line(0,0,vec1.x,vec1.y);
    
    //Second vector
      strokeWeight(10);
      stroke(250,0,250);
      line(0,0,vec2.x,vec2.y);
      
    //Difference vector
      strokeWeight(5);
      stroke(0,250,250);
      line(vec1.x,vec1.y,vec2.x,vec2.y);
    }

现在我想添加箭头,并将其美化。理想的、长期的完美将是3Blue1Brown:

推荐答案

我找到了一个答案here,例如,它允许在两点(或两个位置向量的末端)之间绘制一个向量:

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


function draw() {
  background(240);

  let v0 = createVector(250,250); //Beginning point at center canvas.
  let v1 = createVector(50,50);   //Ending point at the tip of this positional vec.

  drawArrow(v0, v1, 'red'); //Function that draws a red vector from vec0 to vec1.
}


// draw an arrow for a vector at a given base position
function drawArrow(base, vec, myColor) {
  stroke(myColor);
  strokeWeight(4);
  fill(myColor);
  translate(base.x, base.y); //Will transport the object line (below) to the tip of the positional vector v1
  line(0, 0, vec.x, vec.y);  //The line from the O to the tip of v1
  rotate(vec.heading()); //Rotates the following triangle the angle of v1
  let arrowSize = 7; // Determines size of the vector arrowhead (triangle).
  translate(vec.mag() - arrowSize, 0); //Will translate a triangle below by the modulus of v1
  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
}

或此处是从画布中心到鼠标尖端的矢量:

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


function draw() {
  background(240);

  let v0 = createVector(250,250);
  let v1 = createVector(mouseX - 250, mouseY - 250);

  drawArrow(v0, v1, 'red');
}


// draw an arrow for a vector at a given base position
function drawArrow(base, vec, myColor) {
  stroke(myColor);
  strokeWeight(4);
  fill(myColor);
  translate(base.x, base.y);
  line(0, 0, vec.x, vec.y);
  rotate(vec.heading());
  let arrowSize = 7;
  translate(vec.mag() - arrowSize, 0);
  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
}

这里不只是一个向量,而是用上面的代码创建的实际(随机)向量场,调整了Daniel Shiffman的行here:

var inc = 0.1;
scl = 35;
var cols,rows;

function setup() {
  createCanvas(500,500);
  cols = floor(width/scl);
  rows = floor(height/scl);
  }



function draw() {
  background(255);
  var yoff = 0;
  loadPixels();
  for (var y = 0; y < rows; y++) {
    var xoff = 0;
    for (var x = 0; x < cols; x++) {
      var index = (x + y * width)*4;
      var angle = noise(xoff,yoff) * TWO_PI;
      var v = p5.Vector.fromAngle(angle);
      xoff +- inc;
      fill('blue');
      stroke('blue');
      push();
      translate(x*scl,y*scl);
      rotate(v.heading());
      line(0,0,0.5*scl,0);
      let arrowSize = 7;
      translate(0.5*scl - arrowSize, 0);
      triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
      pop();
    }
    yoff += inc;
  }
}

遗憾的是,左上角的原点使得用数学方式表示的物理场相当误导,传达了场逆时针流动的直觉:

var inc = 0.1;
scl = 35;
var cols,rows;

function setup() {
  createCanvas(500,500);
  cols = floor(width/scl);
  rows = floor(height/scl);
  }



function draw() {
  background(255);
  var yoff = 0;
  loadPixels();
  for (var y = 0; y < rows; y++) {
    var xoff = 0;
    for (var x = 0; x < cols; x++) {
      var index = (x + y * width)*4;
      var angle = noise(xoff,yoff) * TWO_PI;
      //var v = createVector(sin(x)+cos(y),sin(x)*cos(y));
      var v = createVector(y,-x);
      xoff +- inc;
      fill('blue');
      stroke('blue');
      push();
      translate(x*scl,y*scl);
      rotate(v.heading());
      line(0,0,0.5*scl,0);
      let arrowSize = 7;
      translate(0.5*scl - arrowSize, 0);
      triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
      pop();
    }
    yoff += inc;
  }
}

最常见的具有负值和正值以及四个象限的笛卡尔坐标将显示该场实际上是如何顺时针流动的:

但这似乎有一个几乎很简单的修复方法,将计数器重置为从减去行数(和列数)到加上行数(和列数),而不是从零开始。此外,需要在y轴上反转递增值的方向,原点需要平移到画布的中间(height/2,height/2)如果是方形的:

var inc = 0.1;
scl = 35;
var cols,rows;

function setup() {
  createCanvas(500,500);
  cols = floor(width/scl);
  rows = floor(height/scl);
  }



function draw() {
  translate(height/2, height/2);  //moves the origin to bottom left
  scale(1, -1);  //flips the y values so y increases "up"
  background(255);
  var yoff = 0;
  loadPixels();
  for (var y = -rows; y < rows; y++) {
    var xoff = 0;
    for (var x =- cols; x < cols; x++) {
      var index = (x + y * width)*4;
      var angle = noise(xoff,yoff) * TWO_PI;
      //var v = createVector(sin(x)+cos(y),sin(x)*cos(y));
      var v = createVector(y,-x);
      xoff +- inc;
      fill('blue');
      stroke('blue');
      push();
      translate(x*scl,y*scl);
      rotate(v.heading());
      line(0,0,0.5*scl,0);
      let arrowSize = 7;
      translate(0.5*scl - arrowSize, 0);
      triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);
      pop();
    }
    yoff += inc;
  }
}

这篇关于P5.js上每个点都有经典箭头的静态向量场的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

本文给大家介绍Javascript js中实现和PHP一样的时间戳格式化函数的方法,具有一定的参考借鉴价值,需要的朋友可以参考下,我们知道在php中有一个date()函数,可以方便的把时间戳格式化为时间字符串。可是在js中,我们要想实现这种效果,要写好
需求是模板字符串中不允许出现script 标签、不允许有javascript: 和 .js 文件引用,主要方法如下: clearScriptTag (str) { const reg = /script[^]*([\S\s]*?)\/script/gim; // 清除标签内 相关 xss 安全代码 const reg1 = /javascript:/gim; const reg2 = / *.js/gim; if (reg.test(str)) { str
javascript中Replace全部替换字符用法实例代码,替换1次和多次,主要是正则表达式 var r= "1\n2\n3\n";//将字母\n替换成分号alert(r.replace("\n",";"));//结果:1;2\n3\n 只替换了第一个var r= "1\n2\n3\n";//将字母\n替换成分号alert(r.replace(/\n/g, ";"));//结果:1;2;3; replac
js输出当前日期和时间的实例代码,具体实例代码如下,有兴趣的朋友可以尝试运行下。 !doctype htmlhtml lang="en" head meta charset="UTF-8" title获取当前时间/title /head body script type="text/javascript" /** *获取当前时间 *format=1精确到天 *format=2精确到秒 */ function
p5.js WebGL 3d graphics covered by 2d background when rotated(P5.js旋转时被2D背景覆盖的WebGL 3D图形)
How would I go about writing a program to rotate at point around a sphere based on an angle as if walking around it?(我该如何编写一个程序,让它以一个角度为基础,在球体周围的点上旋转,就像绕着它走一样?)