📜  如何在 p5.js 中获取不同形状的边界框?

📅  最后修改于: 2022-05-13 01:56:45.371000             🧑  作者: Mango

如何在 p5.js 中获取不同形状的边界框?

在本文中,我们将看到如何获得不同形状的边界框。我们将使用 P5.js,它是一个 Javascript 框架创意编程环境,非常受 Processing 启发。

边界框:边界框基本上只是一个限制形状的矩形,从技术上讲,它是限制形状的表面积最小的矩形。边界框可以有旋转(称为全局边界框),但在本文中,我们将关注轴对齐的边界框(AABB 形状),它们的旋转为零(也称为局部边界框)

注意:形状的边界框是具有最小可能表面积的矩形,用于限制形状。

计算边界框的原因:边界框充当形状的容器,并在图形应用程序中具有多个应用程序(最显着的是用于小部件掩码的 GUI 库)。由于边界框包含形状,因此如果任何其他形状不与边界框相交,那么它也不会与内部形状相交,因此边界框在物理引擎(例如 Box2D)中被大量使用宽相碰撞检测。

p5.js 的基础:这是基础代码(通常适用于每个 p5.js 代码)。



  
    
    
  
  
  

注意:我们只会在每次迭代时更改script.js ,HTML 文件一定会保持原样!

  • 寻找椭圆的边界框:
    /* p5.js Sketch for finding and drawing
       bounding-box of an ellipse*/
    function setup(){
      createCanvas(480, 360);
    }
      
    // Draws bounding-box around the
    // given ellipse!
    function drawBBox(x0, y0, r1, r2){
      
      // Draw only the outline
      // of the rectangle
      noFill();
      
      // Draw the outline in red
      stroke(255, 0, 0);
      rect(x0-r1, y0-r2, 2*r1, 2*r2);
    }
    function draw() {
      let x0 = width/2, y0 = height/2;
      let r1 = 180, r2 = 100;
      
      // Note that `ellipse` takes in
      // diameters not radii!
      ellipse(x0, y0, 2*r1, 2*r2);
      drawBBox(x0, y0, r1, r2);
      
      // We don't want to draw this
      // over and over again
      noLoop();
    }
    

    输出:

  • 寻找圆的边界框:它与椭圆相同,因为圆只是具有相同半径(相同的半长轴和半短轴)的椭圆的特例。
  • 寻找线段的边界框
    /* p5.js Sketch for finding and drawing
      bounding-box of a line-segment*/
    function setup() {
      createCanvas(480, 360);
    }
      
    // Draws bounding-box around the
    // given line-segment!
    function drawBBox(x1, y1, x2, y2) {
      stroke(255, 0, 0);
      noFill();
      let x = min(x1, x2), y = min(y1, y2);
      let w = max(x1, x2) - x, h = max(y1, y2) - y;
      rect(x, y, w, h);
    }
      
    function draw() {
      let x1 = 280, y1 = 80, x2 = 180, y2 = 280;
      line(x1, y1, x2, y2);
      drawBBox(x1, y1, x2, y2);
      noLoop();
    }
    

    输出:

  • 寻找三角形的边界框:寻找三角形的边界框与寻找线段的边界框非常相似。
    /* p5.js Sketch for finding and drawing
      bounding-box of a triangle*/
    function setup() {
      createCanvas(480, 360);
    }
      
    // Draws bounding-box around the
    // given triangle!
    function drawBBox(x1, y1, x2, y2, x3, y3) {
      stroke(255, 0, 0);
      noFill();
      let x = min(x1, x2, x3), y = min(y1, y2, y3);
      let w = max(x1, x2, x3) - x, h = max(y1, y2, y3) - y;
      rect(x, y, w, h);
    }
      
    function draw() {
      let x1 = 240, y1 = 80, x2 = 140;
      let y2 = 280, x3 = 340, y3 = 280;
      
      triangle(x1, y1, x2, y2, x3, y3);
      drawBBox(x1, y1, x2, y2, x3, y3);
      noLoop();
    }
    

    输出:

  • 找到多边形的边界框:三角形是多边形,如果我们找到三角形的边界框,那么找到多边形的边界框应该没有任何困难。我们只需要进行泛化,这样我们就可以拥有任意数量的顶点,我们就完成了。
    /* p5.js sketch for finding and drawing
      bounding-box of a polygon*/
    function setup() {
      createCanvas(480, 360);
    }
      
    // Draws bounding-box around
    // the given polygon!
    function drawBBox(x, y) {
      stroke(255, 0, 0);
      noFill();
      let rx = min(x), ry = min(y);
      let w = max(x) - rx, h = max(y) - ry;
      rect(rx, ry, w, h);
    }
      
    function draw(){
      /* Vertices for a star-polygon (decagon) */
      let x = [240, 268, 334, 286, 298,
               240, 182, 194, 146, 212];
      let y = [80, 140, 150, 194, 260,
               230, 260, 194, 150, 140];
      
      beginShape();
      
      for (let i = 0; i < x.length; ++i)
        vertex(x[i], y[i]);
      fill(255, 217, 0);
      
      // If you don't CLOSE it then it'd
      // draw a chained line-segment
      endShape(CLOSE);
      drawBBox(x, y);
      noLoop();
    }
    

    输出:

寻找边界框是可视化应用程序的重要组成部分。同样在诸如游戏之类的动态应用程序中,不能在不影响性能的情况下在每一帧计算胶囊碰撞检测。因此,在任何复杂的碰撞检查之前,都会对提前退出进行广泛的阶段检查,一旦确定该形状不与其他形状发生碰撞,就会返回 false。如果宽相位检查通过,那么窄相位就会发生实际碰撞检测(OOBB、SAT、胶囊、椭圆体等)!因此,由于各种原因,找到边界框是许多图形丰富的应用程序的重要组成部分。