处理中的高级矩形冲突

时间:2015-09-25 21:15:33

标签: math processing

处理过程中编码(processing.org): 我想知道鼠标或其他形状何时与矩形碰撞, 这很容易,但我有一个问题:我希望它在旋转矩形时起作用(例如:rotate(radians(90)))。

2 个答案:

答案 0 :(得分:4)

凯文和阿萨德的贡献都很有用。

在使用2D渲染器方面,您需要为此推出自己的功能。为此你应该熟悉线性代数的几个位和bob(主要是矢量和矩阵,无论如何只需要几个操作)。

我假设您已经熟悉2D转换(使用pushMatrix()/popMatrix()translate(),rotate(),scale()),如果没有,我热烈推荐2D Transformations Processing tutorial

我将简要地解释一些概念(因为它是它自己的一个重要主题)。

如果您之前使用过translate()/rotate()/scale(),那么所有这些都是在幕后为您处理的矩阵操作。在2D中,转换可以存储在3x3矩阵中,如下所示:

X Y T
1 0 0
0 1 0
0 0 1

旋转和比例存储在第1列和第2列(每个2个值),而转换存储在最后一列中。从理论上讲,你可以使用2x3矩阵而不是3x3矩阵,但NxN矩阵有一些不错的属性。其中一个好处是可以简单地与向量相乘。位置可以存储为矢量,我们希望通过将矢量与变换矩阵相乘来变换矢量。如果将矢量看作单个列向量,则矩阵的3x3形式允许乘法(参见matrix multiplication rules here)。

简而言之:

  1. 您可以将转换存储在矩阵中
  2. 您可以使用乘法
  3. 将这些变换应用于矢量

    回到你的问题,检查一个点是否在应用了转换的框内,你可以这样做:

    将测试点的坐标系转换为框的变换坐标系:

    1. 反转框的转换矩阵和
    2. 将该点乘以反转变换矩阵。
    3. 这一开始可能很难理解,但一种方法是想象你旋转整个世界(坐标系),这样你的旋转盒子是直的(基本上是在相反的方向旋转,或反转转换)然后检查该点是否在框中。

      幸运的是,所有这些矩阵操作都不需要从头开始实施:PMatrix2D处理此问题。

      这是一个基本的评论草图,解释了以上所有内容:

      Box box1,box2;
      
      void setup(){
        size(400,400);
      
        box1 = new Box(200,100);
        box1.translate(75,100);
        box1.rotate(radians(30));
        box1.scale(1.1);
      
        box2 = new Box(100,200);
        box2.translate(275,150);
        box2.rotate(radians(-5));
        box2.scale(.95);
      }
      
      void draw(){
        background(255);
        box1.update(mouseX,mouseY);
        box2.update(mouseX,mouseY);
        box1.draw();
        box2.draw();
      }
      
      class Box{
      
        PMatrix2D coordinates = new PMatrix2D();//box coordinate system
        PMatrix2D reverseCoordinates = new PMatrix2D();//inverted coordinate system
      
        PVector reversedTestPoint = new PVector();//allocate reversed point as vector
        PVector testPoint = new PVector();//allocate regular point as vector
      
      
        float w,h;//box width and height
        boolean isHovered;
      
        Box(float w,float h){
          this.w = w;
          this.h = h;
        }
        //whenever we update the regular coordinate system, we update the reversed one too
        void updateReverseCoordinates(){
          reverseCoordinates = coordinates.get();//clone the original coordinate system
          reverseCoordinates.invert();//simply invert it
        }
      
        void translate(float x,float y){
          coordinates.translate(x,y);  
          updateReverseCoordinates();
        }
        void rotate(float angle){
          coordinates.rotate(angle);  
          updateReverseCoordinates();
        }
        void scale(float s){
          coordinates.scale(s);
          updateReverseCoordinates();
        }
        boolean isOver(float x,float y){
          reversedTestPoint.set(0,0);//reset the reverse test point
          testPoint.set(x,y);//set the x,y coordinates we want to test
          //transform the passed x,y coordinates to the reversed coordinates using matrix multiplication
          reverseCoordinates.mult(testPoint,reversedTestPoint);
          //simply test the bounding box
          return ((reversedTestPoint.x >= 0 && reversedTestPoint.x <= w) && 
                  (reversedTestPoint.y >= 0 && reversedTestPoint.y <= h));
        }
      
        void update(float x,float y){
          isHovered = isOver(x,y);
        }
        void draw(){
          if(isHovered) fill(127);
          else          fill(255);
          pushMatrix();
          applyMatrix(coordinates);
          rect(0,0,w,h);
          popMatrix();
        }
      
      }
      

答案 1 :(得分:1)

您正在寻找modelX()modelY()功能。只需传入mouseXmouseY(z为0)即可找到旋转空间中鼠标的位置。同样,传递矩形的位置以找到它们的旋转点。

以下是参考文献中的示例:

void setup() {
  size(500, 500, P3D);
  noFill();
}

void draw() {
  background(0);

  pushMatrix();
  // start at the middle of the screen
  translate(width/2, height/2, -200);     
  // some random rotation to make things interesting
  rotateY(1.0); //yrot);
  rotateZ(2.0); //zrot);
  // rotate in X a little more each frame
  rotateX(frameCount / 100.0);
  // offset from center
  translate(0, 150, 0);

  // draw a white box outline at (0, 0, 0)
  stroke(255);
  box(50);

  // the box was drawn at (0, 0, 0), store that location
  float x = modelX(0, 0, 0);
  float y = modelY(0, 0, 0);
  float z = modelZ(0, 0, 0);
  // clear out all the transformations
  popMatrix();

  // draw another box at the same (x, y, z) coordinate as the other
  pushMatrix();
  translate(x, y, z);
  stroke(255, 0, 0);
  box(50);
  popMatrix();
}