gpt4 book ai didi

math - 高级矩形碰撞处理

转载 作者:行者123 更新时间:2023-12-02 09:31:22 25 4
gpt4 key购买 nike

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

最佳答案

Kevin 和 Asad 的贡献都很有用。

在使用 2D 渲染器方面,您需要为此推出自己的功能。为此,您应该熟悉线性代数的一些知识(主要是向量和矩阵,无论如何也只有一些运算)。

我假设您已经熟悉 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

旋转和缩放存储在第一列和第二列中(各 2 个值),而平移存储在最后一列中。理论上,您可以使用 2x3 矩阵代替 3x3 矩阵,但 NxN 矩阵有一些很好的属性。好处之一是与向量相乘很简单。位置可以存储为向量,我们希望通过将向量与变换矩阵相乘来变换向量。如果将向量视为单列向量,则 3x3 形式的矩阵允许乘法(请参阅 matrix multiplication rules here )。

简而言之:

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

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

通过以下方式将测试点的坐标系转换为框的变换坐标系:

  1. 反转盒子的变换矩阵并
  2. 将点乘以逆变换矩阵。

一开始这可能很难理解,但一种看待方法是想象你旋转整个“世界”(坐标系),这样你的旋转框就是直的(本质上是沿相反方向旋转,或反转变换)然后检查该点是否在框中。

幸运的是,所有这些矩阵运算不需要从头开始实现: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();
}

}

关于math - 高级矩形碰撞处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32790770/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com