• 不规则图形碰撞检测


    对于矩形碰撞,很多人都知道。但面对多边形图形,大多数采用多矩形覆盖的方式。
    但是我不是很喜欢这种方式,我所采用的是利用一个经典算法:
    SAT 一种可以快速检测不规则的凸多边形是否碰撞的算法
     给出两个凸多边形体,如果我们能找到一个轴线,使两物体在此轴线上的投影不重叠,则这两个物体之间没有发生碰撞,这个轴线叫做Separating Axis(红色轴线)。

     

     

    对于2D来说,红色线就是垂直与多边形边的轴。 

     

    因此,如果我们要检查两多边形是否碰撞,就去检查两多边形在每个所有可能的轴上的投影是否重叠。 

      

     /// <summary>

    /// 检测2个矩形是否发生碰撞
    /// </summary>
    /// <returns></returns>
    public static bool IsIntersect (Vector2[] A, Vector2[] B)
     {
        Vector2 AX, AY, BX, BY;
        AX = new Vector2();
        AY = new Vector2();
        BX = new Vector2();
        BY = new Vector2();
        
        AX.X = A[0].X - A[1].X;
        AX.Y = A[0].Y - A[1].Y;              
        AY.X = A[0].X - A[3].X;             
        AY.Y = A[0].Y - A[3].Y;              
        BX.X = B[0].X - B[1].X;             
        BX.Y = B[0].Y - B[1].Y;              
        BY.X = B[0].X - B[3].X;             
        BY.Y = B[0].Y - B[3].Y;              
        //对于AX上:             
        if (Tmp(AX, A, B)) return false;             
        if (Tmp(AY, A, B)) return false;            
        if (Tmp(BX, A, B)) return false;             
        if (Tmp(BY, A, B)) return false;             
        return true;        
    }
              
    private static bool Tmp(Vector2 IS,Vector2[] A,Vector2[] B)
     {
        float[] v = new float[4]; 
        for (int i = 0; i < 4; i++)
        {                 
            float tmp = (IS.X * A[i].X + IS.Y * A[i].Y) / (IS.X * IS.X + IS.Y * IS.Y);
                     v[i] = tmp * IS.X * IS.X + tmp * IS.Y * IS.Y;            
        }
        float[] vv = new float[4];
        for (int i = 0; i < 4; i++)
        {
            float tmp = (IS.X * B[i].X + IS.Y * B[i].Y) / (IS.X * IS.X + IS.Y * IS.Y);
                      vv[i] = tmp * IS.X * IS.X + tmp * IS.Y * IS.Y;
        }
        if (Math.Max(Math.Max(v[0], v[1]),Math.Max(v[2],v[3])) >Math.Min(Math.Min(vv[0],vv[1]),Math.Min(vv[2],vv[3])) && Math.Min(Math.Min(v[0],v[1]),Math.Min(v[2],v[3])) < Math.Max(Math.Max(vv[0],vv[1]),Math.Max(vv[2],vv[3]))) {
         return false
        }//表示暂时不知道是否碰撞             
        else return true;//表示知道未碰撞
    }
    其中需要的参数为矩形的四个点坐标(一共八个点),矩形四个点坐标要求按顺序(顺时针或者逆时针都可以)传入。(因为项目中不涉及超过四个以上顶点的检测,所以只实现了矩形的检测。)
  • 相关阅读:
    偶对学习C#以及理解.Net平台的一些看法(二,Junior Bibliography)
    聊聊编程那些破事0.Prehistory
    偶对学习C#以及理解.Net平台的一些看法(一,Prerequisites)
    [转帖]c#.net常用函数列表
    一个编程小题目引发的思考(上)
    geoTools学习笔记001(简介)
    ArcGIS Server 10安装配置(JAVA)
    ARCGIS中label(标注)和Annotation(注记
    JSTL入门开发包详解
    基于C/S的网盘设计(JAVA) 网盘源码实现部分功能
  • 原文地址:https://www.cnblogs.com/Kurodo/p/2628688.html
Copyright © 2020-2023  润新知