计算移动圆的碰撞,不重叠边界
假设我有一个圆在矩形区域内弹跳。在某个时刻,这个圆将与矩形的一个表面碰撞并反射回来。我这样做的通常方法是让圆与边界重叠,然后反映速度矢量。圆实际上与边界重叠的事实通常不是问题,在低速时也不是很明显。在高速行驶时,很明显圆圈正在做一些不应该做的事情。
我想做的是以编程方式考虑反射,并将圆圈放置在正确的位置,然后再将其显示在屏幕上。这意味着我必须计算它到达当前位置和未来位置之间边界的点——而不是计算它的新位置,然后检查它是否到达边界。
这比通常的圆形/矩形碰撞问题稍微复杂一些。我对应该如何做有一个模糊的想法 - 基本上在当前位置和新位置之间创建一个边界矩形,这带来了它自己的一系列问题(因为矩形是根据圆的方向旋转的)速度)。但是,我认为这是一个常见问题,并且已经存在通用解决方案。
此类问题有通用的解决方案吗?也许我应该研究一些基本理论?
Let's say I have circle bouncing around inside a rectangular area. At some point this circle will collide with one of the surfaces of the rectangle and reflect back. The usual way I'd do this would be to let the circle overlap that boundary and then reflect the velocity vector. The fact that the circle actually overlaps the boundary isn't usually a problem, nor really noticeable at low velocity. At high velocity it becomes quite clear that the circle is doing something it shouldn't.
What I'd like to do is to programmatically take reflection into account and place the circle at it's proper position before displaying it on the screen. This means that I have to calculate the point where it hits the boundary between it's current position and it's future position -- rather than calculating it's new position and then checking if it has hit the boundary.
This is a little bit more complicated than the usual circle/rectangle collision problem. I have a vague idea of how I should do it -- basically create a bounding rectangle between the current position and the new position, which brings up a slew of problems of it's own (Since the rectangle is rotated according to the direction of the circle's velocity). However, I'm thinking that this is a common problem, and that a common solution already exists.
Is there a common solution to this kind of problem? Perhaps some basic theories which I should look into?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
由于只有一个圆形和一个矩形,因此实际上非常简单。半径为 r 的圆在尺寸为 w、h 的矩形内弹跳可以被视为与圆中心的点 p 相同,在矩形
(wr), (hr)
内。现在位置更新变得简单了。给定您在位置
x, y
处的点以及每帧速度dx, dy
,更新后的位置为x+dx, y+dy
> - 除非您跨越边界。比如说,如果你最终得到x+dx > W
(令W = wr
),然后执行以下操作:对于
y
也类似。您必须为每个维度中的相反边界设置类似的(反射的)检查。Since you just have a circle and a rectangle, it's actually pretty simple. A circle of radius
r
bouncing around inside a rectangle of dimensionsw, h
can be treated the same as a pointp
at the circle's center, inside a rectangle(w-r), (h-r)
.Now position update becomes simple. Given your point at position
x, y
and a per-frame velocity ofdx, dy
, the updated position isx+dx, y+dy
- except when you cross a boundary. If, say, you end up withx+dx > W
(lettingW = w-r
), then you do the following:And similarly for
y
. You'll have to set up a similar (reflected) check for the opposite boundaries in each dimension.在每一步中,您都可以计算下一帧的圆的投影/预期位置。
如果它位于矩形之外,那么您可以使用从旧圆位置到矩形边缘的距离以及下一个位置所在的“超过”矩形边缘的量(互穿)来线性插值并确定精确时间当圆“碰到”矩形边缘时。
例如,如果圆距离矩形边缘 10 个像素,则预测将移动到超出它的 5 个像素,您知道,对于时间步长的 2/3(10/15),它会在其原始路径上移动,则为反映并继续在剩余 1/3 时间步长(5/15)的新路径上。通过计算运动的这两个部分并将平移“相加”在一起,您可以找到正确的新位置。
(当然,如果你撞到拐角附近,情况会变得更加复杂,因为在时间步长期间,不同的边缘可能会发生多次碰撞。如果你有多个圆圈在移动,事情就会变得更加复杂。但这就是你的地方可以从您询问的案例开始)
At each step, you can calculate the projected/expected position of the circle for the next frame.
If this lies outside the rectangle, then you can then use the distance from the old circle position to the rectangle's edge and the amount "past" the rectangle's edge that the next position lies at (the interpenetration) to linearly interpolate and determine the precise time when the circle "hits" the rectangle edge.
For example, if the circle is 10 pixels away from the rectangle's edge, then is predicted to move to 5 pixels beyond it, you know that for 2/3rds of the timestep (10/15ths) it moves on its orginal path, then is reflected and continues on its new path for the remaining 1/3rd of the timestep (5/15ths). By calculating these two parts of the motion and "adding" the translations together, you can find the correct new position.
(Of course, it gets more complicated if you hit near a corner, as there may be several collisions during the timestep, off different edges. And if you have more than one circle moving, things get a lot more complex. But that's where you can start for the case you've asked about)
跨越矩形边界的反射非常简单。只需获取物体通过边界的量并从边界位置中减去它即可。例如,如果没有反射的位置为(-0.8,-0.2),左上角位于(0,0),则反射位置将为(0.8,0.2)。
Reflection across a rectangular boundary is incredibly simple. Just take the amount that the object passed the boundary and subtract it from the boundary position. If the position without reflecting would be (-0.8,-0.2) for example and the upper left corner is at (0,0), the reflected position would be (0.8,0.2).