两个形状之间的碰撞
Collision between two shape
我正在制作有关处理的动画。
但是,我对下面的代码有疑问:
因此,您可以在输出中看到,球在 window 上到处都是。我想为球做一个障碍。球可以从 middle
传出,但如果它击中线,它会以 (int)random(1, 3)
.
的速度移动到某个地方
怎么做?
这是我想要实现的目标的图片:
实现此目的的一种方法是在球通过中间时检查碰撞,特别是当球的速度会使 y 从 < height/2 传到 > height/2.[=11 时=]
像这样:
if (((y < height/2 && y+dirY > height/2) || (y > height/2 && y+dirY < height/2)) && (x < width/2-middle || x > width/2+middle)){
dirY = (int) random (1,3);
dirX = (int) random (1,3);
}
(更合适的解决方案是在球的边缘越过障碍物时创建碰撞,但我会把它留给你)
我不会写代码,但我会告诉你如何计算它,它并不难。
取一个圆,我们知道圆心和半径。
取一条我们知道起点和终点的线。
- 如果从
center
到 startpoint
或 endpoint
的距离小于 radius
(例如点在圆内),则该线与圆相交
- 如果
startpoint
X 在中心左侧 (sX < cX),endpoint
X 在中心右侧 (eX > cX),并且它们的 Y 和center
Y 小于 radius
(cY - sY < r)
请注意,这仅适用于带有水平线的简单情况。例如,通常最好真正使用矢量计算来确定从中心到线的距离。这将允许您使用对角线等。
对于您的玩具模型,处理碰撞的最简单方法是考虑碰撞区。所以,
- 建立碰撞区界限x1、x2、y1、y2。当球的中心进入这个区域时,碰撞规则适用。
- 考虑弹性碰撞:你的球只与水平线碰撞,所以只有速度的垂直分量会受到影响,而且它永远不会失去速度。
- 考虑使用大量初始条件测试您的玩具模型,这样您就可以发现由于模型较小、您使用的值等原因造成的任何伪影。 (我已经修改了小球的初始位置为一个随机的初始位置,运行模型几次,看看它在不同初始条件下的表现如何)。
int dirX = (int)random(1, 3);
int dirY = (int)random(1, 3);
//int x = 20, y = 20;
int middle = 20;
int x = (int)random(20, 180);
int y = (int)random(20, 80);
int x1, x2, y1, y2;
void setup() {
size(200,200);
// collision zone limits
x1 = (width/2 - middle) + 20/2 - 1; // 89
x2 = (width/2 + middle) - 20/2 + 1; // 111
y1 = height/2 - 20/2 + 1; // 91
y2 = height/2 + 20/2 - 1; // 109
}
void draw() {
background(255);
ellipse(x, y, 20, 20);
line(0, height/ 2, width/2 - middle, height/2); // (0, 100, 80, 100)
line(width/2 + middle, height/2, width, height/2); // (120, 100, 200, 100)
x += dirX;
y += dirY;
if (x > width || x < 0)
dirX *= -1;
if (y > height || y < 0)
dirY *= -1;
if ((x < x1 && y > y1 && y < height/2 && dirY > 0) || // upper left and going down
(x < x1 && y > height/2 && y < y2 && dirY < 0) || // lower left and going up
(x > x2 && y > y1 && y < height/2 && dirY > 0) || // upper right and going down
(x > x2 && y > height/2 && y < y2 && dirY < 0)) // lower right and going up
dirY *= -1;
}
对于更复杂的模型,可以考虑更复杂的情况,例如线的末端向后碰撞,球的轮廓与线的碰撞等
我正在制作有关处理的动画。
但是,我对下面的代码有疑问:
因此,您可以在输出中看到,球在 window 上到处都是。我想为球做一个障碍。球可以从 middle
传出,但如果它击中线,它会以 (int)random(1, 3)
.
怎么做?
这是我想要实现的目标的图片:
实现此目的的一种方法是在球通过中间时检查碰撞,特别是当球的速度会使 y 从 < height/2 传到 > height/2.[=11 时=]
像这样:
if (((y < height/2 && y+dirY > height/2) || (y > height/2 && y+dirY < height/2)) && (x < width/2-middle || x > width/2+middle)){
dirY = (int) random (1,3);
dirX = (int) random (1,3);
}
(更合适的解决方案是在球的边缘越过障碍物时创建碰撞,但我会把它留给你)
我不会写代码,但我会告诉你如何计算它,它并不难。
取一个圆,我们知道圆心和半径。
取一条我们知道起点和终点的线。
- 如果从
center
到startpoint
或endpoint
的距离小于radius
(例如点在圆内),则该线与圆相交 - 如果
startpoint
X 在中心左侧 (sX < cX),endpoint
X 在中心右侧 (eX > cX),并且它们的 Y 和center
Y 小于radius
(cY - sY < r)
请注意,这仅适用于带有水平线的简单情况。例如,通常最好真正使用矢量计算来确定从中心到线的距离。这将允许您使用对角线等。
对于您的玩具模型,处理碰撞的最简单方法是考虑碰撞区。所以,
- 建立碰撞区界限x1、x2、y1、y2。当球的中心进入这个区域时,碰撞规则适用。
- 考虑弹性碰撞:你的球只与水平线碰撞,所以只有速度的垂直分量会受到影响,而且它永远不会失去速度。
- 考虑使用大量初始条件测试您的玩具模型,这样您就可以发现由于模型较小、您使用的值等原因造成的任何伪影。 (我已经修改了小球的初始位置为一个随机的初始位置,运行模型几次,看看它在不同初始条件下的表现如何)。
int dirX = (int)random(1, 3);
int dirY = (int)random(1, 3);
//int x = 20, y = 20;
int middle = 20;
int x = (int)random(20, 180);
int y = (int)random(20, 80);
int x1, x2, y1, y2;
void setup() {
size(200,200);
// collision zone limits
x1 = (width/2 - middle) + 20/2 - 1; // 89
x2 = (width/2 + middle) - 20/2 + 1; // 111
y1 = height/2 - 20/2 + 1; // 91
y2 = height/2 + 20/2 - 1; // 109
}
void draw() {
background(255);
ellipse(x, y, 20, 20);
line(0, height/ 2, width/2 - middle, height/2); // (0, 100, 80, 100)
line(width/2 + middle, height/2, width, height/2); // (120, 100, 200, 100)
x += dirX;
y += dirY;
if (x > width || x < 0)
dirX *= -1;
if (y > height || y < 0)
dirY *= -1;
if ((x < x1 && y > y1 && y < height/2 && dirY > 0) || // upper left and going down
(x < x1 && y > height/2 && y < y2 && dirY < 0) || // lower left and going up
(x > x2 && y > y1 && y < height/2 && dirY > 0) || // upper right and going down
(x > x2 && y > height/2 && y < y2 && dirY < 0)) // lower right and going up
dirY *= -1;
}
对于更复杂的模型,可以考虑更复杂的情况,例如线的末端向后碰撞,球的轮廓与线的碰撞等