碰撞检测

本文介绍了一种用于碰撞检测的有效算法,包括矩形重叠测试、线段相交测试及求交点的方法。提供了完整的Java代码实现,适用于游戏开发、图形学等领域中需要进行碰撞检测的应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

碰撞检测——矩形重叠碰撞测试,线段相交碰撞测试,线段交点
// rectangle hit test
public static boolean rectHitTest(int x1, int y1, int x2, int y2, int x3,
int y3, int x4, int y4) {
if (Math.max(x1, x2) < Math.min(x3, x4)
|| Math.max(y1, y2) < Math.min(y3, y4)
|| Math.min(x1, x2) > Math.max(x3, x4)
|| Math.min(y1, y2) > Math.max(y3, y4)) {
return false;
}
return true;
}
// segment hit test
public static boolean segmentHitTest(int x1, int y1, int x2, int y2,
int x3, int y3, int x4, int y4) {
// fast hit test
if (!rectHitTest(x1, y1, x2, y2, x3, y3, x4, y4)) {
return false;
}
// segment hit test judgement
/**/
if (vectorProduct(x1 - x3, y1 - y3, x4 - x3, y4 - y3)
* vectorProduct(x2 - x3, y2 - y3, x4 - x3, y4 - y3) <= 0
&& vectorProduct(x3 - x1, y3 - y1, x2 - x1, y2 - y1)
* vectorProduct(x4 - x1, y4 - y1, x2 - x1, y2 - y1) <= 0) {
return true;
}
/**/
return false;
}
/**
*
* @param x1
* @param y1
* @param x2
* @param y2
* @param x3
* @param y3
* @param x4
* @param y4
* @return int array
* if return null, then the two segments are not crossed
* if return array.length = 2, then segments are crossed at x=array[0], y=array[1]
* if return array.length = 4, then segments are overlaped from
* coordinate (array[0],array[1]) to (array[2], array[3])
* if return else then means error
*/
public static int[] segmentHitPoint(int x1, int y1, int x2, int y2, int x3,
int y3, int x4, int y4) {
if (!segmentHitTest(x1, y1, x2, y2, x3, y3, x4, y4))
return null;
int k1, a1, k2, a2, x, y;
int mathShift = 10;
// on the same vertical line
if (x1 == x2 && x3 == x4 && x1 == x2) {
int maxY = Math.max(Math.max(y1, y2), Math.max(y3, y4));
int minY = Math.min(Math.min(y1, y2), Math.min(y3, y4));
int[] arrayY = new int[] { y1, y2, y3, y4 };
int[] result = new int[] { x1, 0, x1, 0 };
int index = 1, i = 0;
while (i < 4 && index < 4) {
if (arrayY[i] != maxY && arrayY[i] != minY) {
result[index] = arrayY[i];
index += 2;
}
i++;
}
return result;
} else if (x1 == x2) {
k2 = (y3 - y4 << mathShift) / (x3 - x4);
a2 = y3 - (k2 * x3 >> mathShift);
x = x1;
y = (x * k2 >> mathShift) + a2;
} else if (x3 == x4) {
k1 = (y1 - y2 << mathShift) / (x1 - x2);
a1 = y1 - (k1 * x1 >> mathShift);
x = x3;
y = (x * k1 >> mathShift) + a1;
}
// normal state
else {
k1 = (y1 - y2 << mathShift) / (x1 - x2);
k2 = (y3 - y4 << mathShift) / (x3 - x4);
if (k1 == k2) {
int maxX = Math.max(Math.max(x1, x2), Math.max(x3, x4));
int minX = Math.min(Math.min(x1, x2), Math.min(x3, x4));
int[] arrayX = new int[] { x1, x2, x3, x4 };
int[] arrayY = new int[] { y1, y2, y3, y4 };
int[] result = new int[4];
int index = 0, i = 0;
while (i < 4 && index < 4) {
if (arrayX[i] != maxX && arrayX[i] != minX) {
result[index++] = arrayX[i];
result[index++] = arrayY[i];
}
i++;
}
return result;
}
a1 = y1 - (k1 * x1 >> mathShift);
a2 = y3 - (k2 * x3 >> mathShift);
x = (a2 - a1 << mathShift) / (k1 - k2);
y = (x * k1 >> mathShift) + a1;
}
return new int[] { x, y };
}
// get the vector product
private static int vectorProduct(int x1, int y1, int x2, int y2) {
return x1 * y2 - x2 * y1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值