Java中模拟体积碰撞

一、矩形与矩形碰撞(AABB算法)

适用场景:轴对齐的矩形物体(如UI元素、简单障碍物)。
实现原理:通过比较两个矩形的边界是否在x轴和y轴上重叠。若全部重叠则发生碰撞。
代码:

class Rectangle {
double x, y, width, height;
public boolean intersects(Rectangle other) {
return (this.x < other.x + other.width) &&
(this.x + this.width > other.x) &&
(this.y < other.y + other.height) &&
(this.y + this.height > other.y);
}
}

二、圆形与圆形碰撞

适用场景:圆形或近似圆形的物体(如小球、粒子效果)。
实现原理:计算两圆心距离,若小于半径之和则碰撞。
代码:

class Circle {
double x, y, radius;
public boolean intersects(Circle other) {
double dx = this.x - other.x;
double dy = this.y - other.y;
double distance = Math.sqrt(dxdx + dydy);
return distance < (this.radius + other.radius);
}
}

三、矩形与圆形碰撞

适用场景:混合形状的交互(如方盒与滚动物体)。
实现原理:将圆形投影到矩形的最近点,检测该点与圆心的距离是否小于半径。
代码示例:

public static boolean isColliding(Rectangle rect, Circle circle) {
// 计算圆心到矩形边界的最近点
double closestX = clamp(circle.x, rect.x, rect.x + rect.width);
double closestY = clamp(circle.y, rect.y, rect.y + rect.height);
// 计算距离并比较
double dx = circle.x - closestX;
double dy = circle.y - closestY;
return (dxdx + dydy) < (circle.radius * circle.radius);
}

private static double clamp(double value, double min, double max) {
return Math.max(min, Math.min(max, value));
}

四、多边形与任意形状碰撞

适用场景:复杂形状(如不规则多边形、自定义图形)。
实现原理:使用分离轴定理(SAT),通过检查所有可能的分离轴是否存在投影不重叠的情况。
关键步骤:

提取多边形的边,并计算每条边的法线作为分离轴。
将所有顶点投影到各轴上,检测投影是否重叠。
若所有轴均存在重叠,则判定为碰撞。
代码片段(以多边形与圆形为例):

public static boolean satCollision(Polygon poly, Circle circle) {
// 将多边形边转换为分离轴
for (int i = 0; i < poly.npoints; i++) {
int next = (i + 1) % poly.npoints;
double edgeX = poly.xpoints[next] - poly.xpoints[i];
double edgeY = poly.ypoints[next] - poly.ypoints[i];
// 计算法线轴
double axisX = -edgeY, axisY = edgeX;
// 投影并检测重叠…
}
// 检测圆形到多边形的最近边…
return overlapOnAllAxes;
}

五、优化策略

空间分区:使用四叉树(2D)或网格划分,减少检测次数。
层级检测:先进行粗略的包围盒检测(AABB),再执行精确检测。
缓存计算结果:对静态物体缓存投影数据,避免重复计算。
面向对象设计:为每种形状(Rectangle、Circle、Polygon)定义独立的类,并封装碰撞检测方法。
工厂模式:通过统一的CollisionDetector类根据对象类型动态选择检测算法。
物理模拟整合:在碰撞后更新物体的速度、方向(需结合动量守恒公式)。

posted @ 2025-03-03 16:36  行路客  阅读(2)  评论(0)    收藏  举报  来源