首页 > 编程语言 >算法实现2D OBB碰撞

算法实现2D OBB碰撞

时间:2022-09-23 15:57:58浏览次数:56  
标签:cube1 float matrix halfScale Vector3 OBB 2D 算法 public

box

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DrawLine : MonoBehaviour {
    public Vector3[] p = new Vector3[4];

    public Vector3 up { get; set; }
    public Vector3 right { get; set; }

    private Cube _cube1;
    public Cube cube1 {
        get {
            if (_cube1 == null) {
                _cube1 = new Cube();
                _cube1.halfScale = 1;
            }
            return _cube1;
        }
    }

    public Matrix4x4 matrix;
    public Color color = Color.green;


    private void OnDrawGizmos() {
        Gizmos.color = color;
        Vector3 pos = transform.position;
        //设置与transform相同矩阵
        matrix = Matrix4x4.TRS(pos, transform.rotation, transform.lossyScale);

        up = new Vector3(matrix[0, 1], matrix[1, 1], matrix[2, 1]);
        right = new Vector3(matrix[0, 0], matrix[1, 0], matrix[2, 0]);
        
        p[0] = up - right + pos;
        p[1] = -up - right + pos;
        p[2] = -up + right + pos;
        p[3] = up + right + pos;

        Gizmos.DrawLine(p[0], p[1]);
        Gizmos.DrawLine(p[1], p[2]);
        Gizmos.DrawLine(p[2], p[3]);
        Gizmos.DrawLine(p[3], p[0]);
    }
}

public class Cube {
    public Vector3 center;
    public float halfScale;
    public Quaternion rotate;

    public Vector3 GetPoint1 => center + new Vector3(-halfScale, halfScale, 0);
    public Vector3 GetPoint2 => center + new Vector3(-halfScale, -halfScale, 0);
    public Vector3 GetPoint3 => center + new Vector3(halfScale, -halfScale, 0);
    public Vector3 GetPoint4 => center + new Vector3(halfScale, halfScale, 0);
}

 

检查是否碰撞

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ColliderCheck : MonoBehaviour {
    public DrawLine cube1x;
    public DrawLine cube2x;
    public float lineLength;
    public bool check;
    
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    private void OnDrawGizmos() {
        //判断 cube1 与 cube2 是否相交
        //获取cube2 在 cube的up 和 right 轴上的投影

        check = CheckIsAxis(cube1x, cube2x) && CheckIsAxis(cube2x, cube1x);
        if (check) {
            cube1x.color = Color.red;
            cube2x.color = Color.red;
        } else {
            cube1x.color = Color.green;
            cube2x.color = Color.green;
        }

        if (Input.GetKeyDown(KeyCode.K)) {
            
        }
    }

    /// <summary>
    /// 从矩阵获取坐标
    /// </summary>
    /// <param name="matrix"></param>
    /// <returns></returns>
    public Vector3 GetPosition(Matrix4x4 matrix) {
        var x = matrix.m03;
        var y = matrix.m13;
        var z = matrix.m23;

        return new Vector3(x, y, z);
    }

    /// <summary>
    /// 从矩阵获取旋转
    /// </summary>
    /// <param name="matrix"></param>
    /// <returns></returns>
    public Quaternion GetRotation(Matrix4x4 matrix) {
        //m11 + m22 + m33 = 4w^2
        float qw = Mathf.Sqrt(1f + matrix.m00 + matrix.m11 + matrix.m22) / 2;
        float w = 4 * qw;
        float qx = (matrix.m21 - matrix.m12) / w;
        float qy = (matrix.m02 - matrix.m20) / w;
        float qz = (matrix.m10 - matrix.m01) / w;
        return new Quaternion(qx, qy, qz, qw);
    }

    /// <summary>
    /// 从矩阵获取缩放
    /// </summary>
    /// <param name="m"></param>
    /// <returns></returns>
    public static Vector3 GetScale(Matrix4x4 m) {
        var x = Mathf.Sqrt(m.m00 * m.m00 + m.m01 * m.m01 + m.m02 * m.m02);
        var y = Mathf.Sqrt(m.m10 * m.m10 + m.m11 * m.m11 + m.m12 * m.m12);
        var z = Mathf.Sqrt(m.m20 * m.m20 + m.m21 * m.m21 + m.m22 * m.m22);

        return new Vector3(x, y, z);
    }
    
    private bool CheckIsAxis(DrawLine cube1, DrawLine cube2) {
        //可得y轴上的最小值与最大值
        NewMethod(cube1, cube2, cube1.up, out var maxValue, out var minValue);
        //Debug.Log(minValue + "    " +maxValue);
        //判断y轴是否重合
        bool isOverLayY = false;
        if (maxValue <= cube1.cube1.halfScale && maxValue >= -cube1.cube1.halfScale) {
            isOverLayY = true;
        }

        if (minValue <= cube1.cube1.halfScale && minValue >= -cube1.cube1.halfScale) {
            isOverLayY = true;
        }

        //判断x轴
        NewMethod(cube1, cube2, cube1.right, out var maxValue2, out var minValue2);
        bool isOverLayX = false;
        if (maxValue2 <= cube1.cube1.halfScale && maxValue2 >= -cube1.cube1.halfScale) {
            isOverLayX = true;
        }

        if (minValue2 <= cube1.cube1.halfScale && minValue2 >= -cube1.cube1.halfScale) {
            isOverLayX = true;
        }


        if (isOverLayX && isOverLayY) {
            return true;
        }
        return false;
    }

    private void NewMethod(DrawLine cube1, DrawLine cube2, Vector3 onNormal ,out float maxValue, out float minValue) {
        float[] yArray = new float[4];
        maxValue = 0;
        minValue = 0;
        for (int i = 0; i < 4; i++) {
            Vector3 cube1Pos = cube1.transform.position;
            var line = Vector3.Project(cube2.p[i] - cube1Pos, onNormal);
            float yValue = line.magnitude;
            yArray[i] = yValue;
            //Debug.Log(yValue);
            if (i == 0) {
                maxValue = yValue;
                minValue = yValue;
            } else {
                if (yValue > maxValue) {
                    maxValue = yValue;
                }

                if (yValue < minValue) {
                    minValue = yValue;
                }
            }
        }
    }
}

 

 

 

标签:cube1,float,matrix,halfScale,Vector3,OBB,2D,算法,public
From: https://www.cnblogs.com/sanyejun/p/16722990.html

相关文章

  • C语言经典算法100例
    【程序1】题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?#include<stdio.h>#include<stdlib.h>intmain(){inti,j,k,m;......
  • mask和RectMask2D区别
    1.Mask遮罩的大小与形状依赖于Graphic,而RectMask2D只需要依赖RectTransform2.Mask支持圆形或其他形状遮罩,而RectMask2D只支持矩形3.Mask会增加drawcall4、mask的性......
  • 凸包算法
    凸包的概念:在某个二维平面上的给定一个点集,凸包就是将最外层的点连接起来构成的凸多边形,它能包含点集中所有的点。凸包算法从点集中获取凸包的方法比较常用的有Jarvis步......
  • 「浙江理工大学ACM入队200题系列」问题 A: 零基础学C/C++34—— 3个数比较大小(冒泡排
    深夜写的,代码都还没来得及跑一便,可能有错误,欢迎指出,后续会检验一遍并修改错误.本题是浙江理工大学ACM入队200题第四套中的A题,同时给出了冒泡排序和选择排序算法......
  • 算法练习-第二天【数组】
    数组977.有序数组的平方参考:代码随想录977.有序数组的平方看完题目的第一想法根据题意直接每个元素求平方,然后排个序,提交。时间复杂度O(\(nlogn\))。funcsortedSqua......
  • 算法设计与分析课-实验三-动态规划
    算法设计与分析课实验三第一题矩阵连乘问题:分析:该问题求矩阵连乘积最少乘次数,对于两个矩阵A(i行j列)和B(j行n列),他们相乘的乘次数为ijn,对于两个矩阵只有它们的列和行......
  • CSP 2022 备战 贪心算法
    基本思路:1.建立数学模型来描述问题2.把求解的问题分成若干个子问题3.对每一子问题求解,得到子问题的局部最优解4.把子问题的局部最优解合并成一个解贪心的使用前提:局部......
  • KMP算法
    朴素的模式匹配算法朴素算法就是以主串的每一个字符作为子串的开头,与要匹配的字符串(称为模式串)进行匹配,匹配失败则主串退回到这次匹配首位的下一位,重新进行匹配。主......
  • python基础__十大经典排序算法
    用Python实现十大经典排序算法!排序算法是《数据结构与算法》中最基本的算法之一。排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序......
  • 一段式SM3算法的实现
    C语言#pragmaonce//C语言实现的一段式SM3算法#include<stdio.h>#include<memory>//定义初始值IV,初始值IV是一个常数unsignedcharIV[256/8]{0x73,0x80......