`
dave5177
  • 浏览: 10851 次
文章分类
社区版块
存档分类

利用分离轴定律实现的两个简单的自由选择矩形的碰撞

阅读更多

前几天写一个j2me的2d俯视视角赛车游戏。赛车用可旋转的矩形作为碰撞体,先用自由矩形的外接矩形做预计碰撞,然后再用分离轴定律实现真正的碰撞。我把起实现代码分享给大家:

/**
	 * 两个自由矩形的碰撞检测 sat(分离轴定律)方法
	 * 
	 * @param rectFree_a
	 *            自由矩形a
	 * @param rectFree_b
	 *            自由矩形b
	 * @return
	 */
	public static boolean freeRectIsct(RectFree rectFree_a, RectFree rectFree_b) {//这里的RectFree是我自己实现的一个自由旋转矩形
		Vector2[] axis_proj = new Vector2[4];// 4个投影轴(这里的vector2是也我自己实现的2维向量,内容很简单)
		axis_proj[0] = new Vector2(rectFree_a.ver_d.x - rectFree_a.ver_a.x,
				rectFree_a.ver_d.y - rectFree_a.ver_a.y);
		axis_proj[1] = new Vector2(rectFree_a.ver_a.x - rectFree_a.ver_b.x,
				rectFree_a.ver_a.y - rectFree_a.ver_b.y);
		axis_proj[2] = new Vector2(rectFree_b.ver_d.x - rectFree_b.ver_a.x,
				rectFree_b.ver_d.y - rectFree_b.ver_a.y);
		axis_proj[3] = new Vector2(rectFree_b.ver_a.x - rectFree_b.ver_b.x,
				rectFree_b.ver_a.y - rectFree_b.ver_b.y);

		// 最大最小的投影标量
		float scalar_max_a = 0;
		float scalar_min_a = 0;
		float scalar_max_b = 0;
		float scalar_min_b = 0;

		Vector2 v_translate = null;//平移向量(由于没有设置局部坐标,所以需要矩形平移后再对各个顶点进行投影)
		for (int i = 0; i < 4; i++) {
			if (i == 0)
				v_translate = rectFree_a.ver_a;
			else if (i == 1)
				v_translate = rectFree_a.ver_b;
			else if (i == 2)
				v_translate = rectFree_b.ver_a;
			else
				v_translate = rectFree_b.ver_b;

			Vector2[] vector_proj_b = new Vector2[4];
			//对矩形b的四个顶点投影方法
			vector_proj_b[0] = axis_proj[i].mult(axis_proj[i]
					.dotProduct(rectFree_b.ver_a.add(v_translate.negative()))//negitive()是自己实现的向量的负向量
					/ axis_proj[i].dotProduct(axis_proj[i]));
			vector_proj_b[1] = axis_proj[i].mult(axis_proj[i]
					.dotProduct(rectFree_b.ver_b.add(v_translate.negative()))
					/ axis_proj[i].dotProduct(axis_proj[i]));
			vector_proj_b[2] = axis_proj[i].mult(axis_proj[i]
					.dotProduct(rectFree_b.ver_c.add(v_translate.negative()))
					/ axis_proj[i].dotProduct(axis_proj[i]));
			vector_proj_b[3] = axis_proj[i].mult(axis_proj[i]
					.dotProduct(rectFree_b.ver_d.add(v_translate.negative()))
					/ axis_proj[i].dotProduct(axis_proj[i]));
			float[] scalar_proj_b = new float[4];// 各个顶点投影的标量值
			for (int j = 0; j < 4; j++) {
				scalar_proj_b[j] = vector_proj_b[j].dotProduct(axis_proj[i]);//计算投影点的标量值,(与投影轴的点积)
			}
			scalar_max_b = scalar_proj_b[0];
			scalar_min_b = scalar_proj_b[0];
			for (int j = 1; j < 4; j++) {//简单的计算标量值的最大值和最小值
				if (scalar_proj_b[j] < scalar_min_b)
					scalar_min_b = scalar_proj_b[j];
				if (scalar_proj_b[j] > scalar_max_b)
					scalar_max_b = scalar_proj_b[j];
			}

			Vector2[] vector_proj_a = new Vector2[4];
			//再对矩形a进行同样的计算
			vector_proj_a[0] = axis_proj[i].mult(axis_proj[i]
					.dotProduct(rectFree_a.ver_a.add(v_translate.negative()))
					/ axis_proj[i].dotProduct(axis_proj[i]));
			vector_proj_a[1] = axis_proj[i].mult(axis_proj[i]
					.dotProduct(rectFree_a.ver_b.add(v_translate.negative()))
					/ axis_proj[i].dotProduct(axis_proj[i]));
			vector_proj_a[2] = axis_proj[i].mult(axis_proj[i]
					.dotProduct(rectFree_a.ver_c.add(v_translate.negative()))
					/ axis_proj[i].dotProduct(axis_proj[i]));
			vector_proj_a[3] = axis_proj[i].mult(axis_proj[i]
					.dotProduct(rectFree_a.ver_d.add(v_translate.negative()))
					/ axis_proj[i].dotProduct(axis_proj[i]));
			float[] scalar_proj_a = new float[4];
			for (int j = 0; j < 4; j++) {
				scalar_proj_a[j] = vector_proj_a[j].dotProduct(axis_proj[i]);
			}
			scalar_max_a = scalar_proj_a[0];
			scalar_min_a = scalar_proj_a[0];
			for (int j = 1; j < 4; j++) {
				if (scalar_proj_a[j] < scalar_min_a)
					scalar_min_a = scalar_proj_a[j];
				if (scalar_proj_a[j] > scalar_max_a)
					scalar_max_a = scalar_proj_a[j];
			}

			//碰撞判断(分离轴定律,有任何一个轴使两个凸多边形顶点的投影没有出现交错即两个多边形没有相交)
			if (scalar_min_a > scalar_max_b || scalar_max_a < scalar_min_b)
				return false;
		}

		return true;
	}

 分离轴定律不太了解的可以自行百度。

0
3
分享到:
评论

相关推荐

    碰撞_vceasyx_物理碰撞_

    AABB通过比较两个矩形的边界来判断是否发生碰撞。 实现碰撞检测的基本步骤如下: 1. 定义物体的边界框,通常是物体中心点和半径或宽度和高度。 2. 检查每个物体的边界是否相交。对于AABB,如果两个矩形的最小X坐标...

    html5 javascript 完全弹性碰撞 canvas 物理碰撞

    当两个物体碰撞时,它们的速度、质量和位置会根据动量守恒和能量守恒定律发生变化。具体计算公式包括速度交换、角度修正等步骤,确保碰撞后总动量和总动能保持不变。 JavaScript代码中,我们通常需要维护一个包含...

    collisi:检测碰撞

    分离轴定理是用于检测二维多边形之间碰撞的常用方法,通过寻找两个多边形的投影在所有可能的轴上是否相交来判断。旋转镜像法则是在3D空间中,通过旋转包围盒(Bounding Box)来检测是否发生碰撞。 2. **近似碰撞...

    jbox2D.zip

    3. 连接关节(Joint):关节用于连接两个或多个刚体,实现复杂的动力学效应。例如,可以使用RevoluteJoint创建旋转关节,使物体能够自由旋转;使用DistanceJoint创建固定距离的连接,保持物体间的相对位置。 四、...

    BOX2D引擎JAR文件

    4. **碰撞检测与响应**:Box2D提供了高效的碰撞检测算法,可以准确判断两个物体是否发生碰撞,并根据碰撞类型执行相应的响应,如反弹、摩擦力计算等。 5. **世界(World)**:所有物理实体都存在于一个全局的物理...

    弹跳碰撞

    对于更复杂的碰撞检测,例如两个多边形之间的碰撞,p5.play可能不直接提供支持,但开发者可以利用其他算法如分离轴定理(Separating Axis Theorem)进行实现。 在"弹跳碰撞"的场景中,每个物体的碰撞响应需要正确...

    2D物理演示.rar

    这涉及检测两个形状(如矩形、圆形或复杂多边形)何时相交,并计算出碰撞后的结果,如速度的改变。常见的碰撞检测算法有分离轴定理(Separating Axis Theorem)和SAT的简化版本,如Circle-Circle碰撞检测。 4. **...

    Penguin-project-1.1

    1. **检测碰撞**:通过比较物体的边界,判断它们是否发生重叠,这通常涉及到矩形或圆形的碰撞检测算法,如分离轴定理(Separating Axis Theorem)或简单的相交测试。 2. **确定碰撞点**:找到两个物体接触的精确点...

    project1

    例如,假设我们有两个矩形物体,我们首先检查它们的边界是否重叠。如果重叠,我们计算每个物体速度在碰撞轴上的投影,然后应用上述反射规则。最后,更新物体的位置和速度,以反映新的运动状态。 在"project1-main...

    安徽省滁州市民办高中2017_2018学年高二物理下学期第三次月考试题201806010120

    5. 电磁感应和互感现象:第五题中,两个并排放置的线圈之间存在互感现象。当一个线圈中的电流变化时,会诱导另一个线圈产生感应电流,从而改变两线圈之间的相互作用力。图乙所示的电流变化会导致不同时间点线圈间的...

    2022年大学心理学专业《大学物理(二)》月考试题附解析.pdf

    6. 对于转动惯量,两个圆盘的I与质量、密度、面积及厚度分布有关,题目条件不足以判断哪个更大。 7. 刚体对轴的转动惯量取决于质量、质量和空间分布以及轴的位置,选项B正确。 这些知识点涵盖了大学物理中的多个...

    PhysicsEngine2D:一个简单的2D物理引擎

    3. **碰撞检测(Collision Detection)**:PhysicsEngine2D使用各种算法来检测和处理物体间的碰撞,如分离轴定理(Separating Axis Theorem,SAT)用于多边形碰撞,圆和圆之间的碰撞则使用简单的距离检查。...

    Box2dForFlashGame(中文版)

    2. **碰撞检测**:Box2D内置了高效的碰撞检测算法,能够精确地检测出两个或多个物体之间的碰撞,并提供接触点、法线、分离距离等信息,帮助开发者处理碰撞后的反应。 3. **关节与约束**:Box2D支持多种类型的关节,...

    bounce:反弹那些多边形

    这可以通过各种算法实现,如分离轴定理(Separating Axis Theorem, SAT),该算法能够检测任意两个凸多边形是否相交。对于简单的形状,如矩形,可以使用轴对齐边界框(Axis-Aligned Bounding Box, AABB)进行快速预...

    MarsinEngine:为我们的软件工程课程开发的简单 2D 物理引擎

    3. **关节(Joints)**:在物理模拟中,关节用于连接两个或多个刚体,限制它们的相对运动。常见的关节类型包括铰链关节、滑块关节和固定关节。MarsinEngine可能提供这些基本类型的关节实现,允许开发者创建更复杂的...

    sandbox:C++ 中的 2D 物理引擎

    它们用于快速碰撞检测,因为检查两个AABB是否相交比检查实际形状简单得多。 - 使用AABB树(一种空间分割数据结构)可以进一步加速,通过将场景中的物体分组到不同的AABB节点中,减少需要检查的碰撞对数量。 3. **...

    项目26

    这个环境可能会包含各种物体,它们能够自由移动、相互碰撞,并且遵循物理定律,如牛顿运动定律和碰撞理论。 在JavaScript环境下,Matter.js提供了丰富的API供开发者使用,包括但不限于: 1. **Body**:表示物理...

    class31

    可以使用轴对齐边界框(AABB)或更复杂的碰撞检测算法,如分离轴定理(SAT)。当检测到碰撞时,还需要处理碰撞后的效果,如分数计算、物体破坏等。 6. **动画与帧更新**: 游戏中的动画是通过连续更新和绘制每一帧...

    Asteroids:经典的Java程序游戏“ Asteroids”,由用户控制,包括形状,位置,运动和旋转

    在Java中,可以使用矩形或圆形的边界框进行简单的碰撞检测,或者使用更复杂的算法如分离轴定理(Separating Axis Theorem)来处理更精确的几何形状。 4. **物理模拟**:Asteroids中的物体遵循牛顿运动定律,因此...

    AngryBirds-Stage-6

    JavaScript可以利用矩形或圆形的边界检测方法来判断两个物体是否相交。对于更复杂的形状,可能需要使用到更高级的算法,如分离轴定理(Separating Axis Theorem)来精确地检测碰撞。 再者,作用力的模拟也是...

Global site tag (gtag.js) - Google Analytics