delaunator 没有在 p5js 草图上绘制所有三角形

delaunator not drawing all triangles on a p5js sketch

我正在尝试移植此草图:https://codepen.io/giorgiomartini/pen/JjrOVXq?editors=1010 which uses a similar library: https://cdn.rawgit.com/ironwallaby/delaunay/master/delaunay.js,但我只得到一个三角形。

这是我的代码:https://github.com/GiorgioRemindme/giorgio-martini/blob/main/src/sketches/tris.js

我认为这是有问题的部分:

for (let i = 0; i < triangulation.triangles.length; i += 3) {
  triangles.push(new Triangle(
    pts[triangulation.triangles[i]],
    pts[triangulation.triangles[i + 1]],
    pts[triangulation.triangles[i + 2]]
  ))
}

但是,它只渲染一个三角形,而在 codepen 中它会渲染所有三角形。

这是初始化函数:

  function initializeTriangulation() {
    triangles = [];
    let pts = [];
    // push canvas rect points
    pts.push(p5.createVector(0, 0))
    pts.push(p5.createVector(p5.width, 0))
    pts.push(p5.createVector(p5.width, p5.height))
    pts.push(p5.createVector(0, p5.height))

    // add a certain nb of pts proportionally to the size of the canvas
    // ~~ truncates a floating point number and keeps the integer part, like floor()
    var n = 2
    for (let i = 0; i < n; i++) {
      pts.push(p5.createVector(~~p5.random(p5.width), ~~p5.random(p5.height)))
    }

    // Now, let's use Delaunay.js
    // Delaunay.triangulate expect a list of vertices (which should be a bunch of two-element arrays, representing 2D Euclidean points)
    // and it will return you a giant array, arranged in triplets, representing triangles by indices into the passed array
    // Array.map function let's us create an Array of 2 elements arrays [ [x,y],[x,y],..] from our array of PVector [ PVector(x,y), PVector(x,y), ... ]
    
    let delunaySource = pts.map(pt => [pt.x, pt.y]).flat(Infinity)
    console.log({delunaySource})

    const triangulation = new Delaunator(delunaySource)
    console.log({triangulation})


    //create Triangles object using indices returned by Delaunay.triangulate
    for (let i = 0; i < triangulation.triangles.length; i += 3) {
      triangles.push(new Triangle(
        pts[triangulation.triangles[i]],
        pts[triangulation.triangles[i + 1]],
        pts[triangulation.triangles[i + 2]]
      ))
    }
  }

知道问题出在哪里吗?

谢谢。

您每次绘制三角形时都在重新绘制背景:https://github.com/GiorgioRemindme/giorgio-martini/blob/main/src/sketches/tris.js#L92

    this.draw = function () {
      p5.background(255) // <---- Oops!
      p5.fill(100);
      p5.triangle(this.a.x, this.a.y, this.b.x, this.b.y, this.c.x, this.c.y)
      p5.stroke(0);
      p5.strokeJoin(p5.BEVEL)
      p5.strokeWeight(1)
      p5.triangle(this.a.x, this.a.y, this.b.x, this.b.y, this.c.x, this.c.y);
    }

没有 ReactJS 东西的工作版本:

let triangles
let canvasSize = 600
let vertexAmt
let vertex

let palette = [
  '#42CAFD',
  '#66B3BA',
  '#8EB19D',
  '#F6EFA6',
  '#F0D2D1'
]

function Sketch(p) {
  // helper...
  function getRandomFromArray(items) {
    let result = items[Math.floor(Math.random() * items.length)]
    return result
  }

  p.setup = () => {
    p.createCanvas(300, 300)
    initializeTriangulation()
    p.print(`triangles: ${triangles.length}`);
    p.noLoop();
  }

  p.draw = () => {
    p.background(0)
    triangles.forEach(t => t.draw());
  }

  function initializeTriangulation() {
    triangles = [];
    let pts = [];
    // push canvas rect points
    pts.push(p.createVector(0, 0))
    pts.push(p.createVector(p.width, 0))
    pts.push(p.createVector(p.width, p.height))
    pts.push(p.createVector(0, p.height))

    // add a certain nb of pts proportionally to the size of the canvas
    // ~~ truncates a floating point number and keeps the integer part, like floor()
    var n = 20
    for (let i = 0; i < n; i++) {
      pts.push(p.createVector(~~p.random(p.width), ~~p.random(p.height)))
    }

    // Now, let's use Delaunay.js
    // Delaunay.triangulate expect a list of vertices (which should be a bunch of two-element arrays, representing 2D Euclidean points)
    // and it will return you a giant array, arranged in triplets, representing triangles by indices into the passed array
    // Array.map function let's us create an Array of 2 elements arrays [ [x,y],[x,y],..] from our array of PVector [ PVector(x,y), PVector(x,y), ... ]

    let delunaySource = pts.map(pt => [pt.x, pt.y]).flat(Infinity)
    console.log({
      delunaySource
    })

    const triangulation = new Delaunator(delunaySource)
    console.log({
      triangulation
    })


    //create Triangles object using indices returned by Delaunay.triangulate
    for (let i = 0; i < triangulation.triangles.length; i += 3) {
      console.log("xx: ", triangulation.triangles[i])
      triangles.push(new Triangle(
        pts[triangulation.triangles[i]],
        pts[triangulation.triangles[i + 1]],
        pts[triangulation.triangles[i + 2]]
      ))
    }
  }

  // class for keeping triangles from 3 PVectors
  function Triangle(_a, _b, _c) {
    // PVectors
    this.a = _a
    this.b = _b
    this.c = _c

    // used for drawing lines on triangles
    // number of lines to draw proportionnally to the triangle size
    this.n = ~~(p.dist(_a.x, _a.y, (this.b.x + this.c.x) / 2, (this.b.y + this.c.y) / 2) / p.random(25, 50)) + 1
    // direction point for the lines
    this.drawTo = ~~p.random(3);

    this.draw = function() {
      //p.background(255)
      p.fill(100);
      //p.triangle(this.a.x, this.a.y, this.b.x, this.b.y, this.c.x, this.c.y)
      p.stroke(0);
      p.strokeJoin(p.BEVEL)
      p.strokeWeight(1)
      p.triangle(this.a.x, this.a.y, this.b.x, this.b.y, this.c.x, this.c.y);
    }
  }
}

let inst = new p5(Sketch);
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
<script src="https://unpkg.com/delaunator@4.0.1/delaunator.min.js"></script>