处理过程中编码(processing.org): 我想知道鼠标或其他形状何时与矩形碰撞, 这很容易,但我有一个问题:我希望它在旋转矩形时起作用(例如:rotate(radians(90)))。
答案 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)。
简而言之:
回到你的问题,检查一个点是否在应用了转换的框内,你可以这样做:
将测试点的坐标系转换为框的变换坐标系:
这一开始可能很难理解,但一种方法是想象你旋转整个世界(坐标系),这样你的旋转盒子是直的(基本上是在相反的方向旋转,或反转转换)然后检查该点是否在框中。
幸运的是,所有这些矩阵操作都不需要从头开始实施: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()功能。只需传入mouseX
和mouseY
(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();
}