基于2D多边形的碰撞检测和响应(二)

二、 用于碰撞响应的扩展分离坐标轴方法
检测多边形相交是非常有用的方法,但是可以做更多的事情。当多边形相交时,我想将他们移开以避免他们相交。
 
分离轴的方法可以非常好的用于这种情况,但是还需要作一些额外的工作。必须返回相交的深度,和推开多边形将它们分离的方向。相交的深度和方向的组合称为MTD,或者最小平移距离。这是用于将物体分离的的最小向量。
 
为了计算MTD,我们可以使用分离坐标轴。
 
当物体相交时,我们可以计算两个物体在每一个分离轴上的投影间隔。两个间隔交叠的部分提供了一个推动向量,你需要将其应用到其中一个物体上以便物体在轴上的投影停止交叠

“推动向量”你需要应用于A上将A推开,这样就可以使A和B分开。
 
显然,不能沿着一个随机的轴来推开物体。候选轴是投影在该轴上两个间隔之间交叠最小的那个。并且这个推动向量提供了最小平移距离。
 

bool Intersect(Polygon A, Polygon B, Vector& MTD)
{
    // potential separation axes. they get converted into push
    vectors Vector Axis[32];
    // max of 16 vertices per polygon
    int iNumAxis = 0;
    for(J = A.num_vertices–1, I = 0; I < A. num_vertices; J = I, I ++)
    {
        Vector E = A.vertex[I] – A.vertex[J];
        Axis[iNumAxis++] = Vector(-E.y, E.x);
   
    if (AxisSeparatePolygons(N, A, B))
            return false;
    }
    for(J = B. num_vertices–1, I = 0; I < B.num_vertices; J = I, I ++)
    {
        Vector E = B.vertex[I] – B.vertex[J];
        Axis[iNumAxis++] = Vector(-E.y, E.x);
   
        if (AxisSeparatePolygons (N, A, B))
            return false;
    }
   
    // find the MTD among all the separation vectors
    MTD = FindMTD(Axis, iNumAxis);

    // makes sure the push vector is pushing A away from B
    Vector D = A.Position – B.Position;
    if (D dot MTD < 0.0f)
        MTD = -MTD;

    return true;
}

 

bool AxisSeparatePolygons(Vector& Axis, Polygon A, Polygon B)
{
    float mina, maxa;
    float minb, maxb;

    CalculateInterval(Axis, A, mina, maxa);
    CalculateInterval(Axis, B, minb, maxb);

    if (mina > maxb || minb > maxa)
        return true;

    // find the interval overlap
    float d0 = maxa - minb;
    float d1 = maxb - mina;
    float depth = (d0 < d1)? d0 : d1;

    // convert the separation axis into a push vector (re-normalise
    // the axis and multiply by interval overlap)
    float axis_length_squared = Axis dot Axis;

    Axis *= depth / axis_length_squared;
    return false;
}

 

Vector FindMTD(Vector* PushVectors, int iNumVectors)
{
    Vector MTD = PushVector[0];
    float mind2 = PushVector[0] dot PushVector[0];
    for(int I = 1; I < iNumVectors; I ++)
    {
        float d2 = PushVector[I] * PushVector[I];
        if (d2 < mind2)
        {
            mind2 = d2;
            MTD = PushVector[I];
        }
    }
    return MTD;
}

一旦得到了MTD向量,可以使用如下的方式将他们分开
 

A.Postion += MTD * 0.5f;
B.Position -= MTD * 0.5f;

显然,如果物体A是静态的,那么B将被完全的MTD推开(B.Position-=MTD)而A将不会被推开。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值