【无标题】

OBB碰撞检测算法 python

巴拉巴拉~~~~~

code:

import numpy as np


class OBB:
    def _init__(self, point_set: np.ndarray):
        self.pos = (point_set[0] + point_set[6]) / 2  # 包围盒中心点位置
        self.axisX = self.__norm(point_set[1] - point_set[0])  # 包围盒x轴的方向向量
        self.axisY = self._norm(point_set[3] - point_set[0])  # 包围盒y轴的方向向量
        self.axisZ = self._norm(point_set[0] - point_set[4])  # 包围盒z轴的方向向量
        self.half_size = np.array([self.__get_distance(point_set[0].point_set[1]) / 2,
                                   self._get_distance(point_set[0].point_set[3]) / 2,
                                   self.__get_distance(point_set[0].point_set[4]) / 2])

    def __norm(self, vector):  # 将向量归一化为标准向量
        s = 0
        for e in vector:
            s += e * e
        return vector / (s ** 0.5)

    def __get_distance(self, point_1, point_2):  # 计算两个点的距离
        return ((point_1[0] - point_2[0]) ** 2 + (point_1[1] - point_2[1]) ** 2 + (point_1[2] - point_2[2]) ** 2) ** 0.5


def cross_product(vector1, vector2):  # 向量积
    return np.array(vector1[1] * vector2[2] - vector1[2] * vector2[1],
                    vector1[2] * vector2[0] - vector1[0] * vector2[2],
                    vector1[0] * vector2[1] - vector1[1] * vector2[0])


def getSeparatingPlane(r_pos, plane, box1: OBB, box2: OBB):  # 判断在选定的坐标平面是否有分割平面
    return ((abs(sum(r_pos * plane)) >
             (abs(sum((box1.axisX * box1.half_size[0]) * plane)) +
              abs(sum((box1.axisY * box1.half_size[1]) * plane)) +
              abs(sum((box1.axisZ * box1.half_size[2]) * plane)) +
              abs(sum((box2.axisX * box2.half_size[0]) * plane)) +
              abs(sum((box2.axisY * box2.half_size[1]) * plane)) +
              abs(sum((box2.axisZ * box2.half_size[2]) * plane)))))

def isCollision(box1:OBB,box2:OBB): #判断两个OBB是否发生碰撞
    r_pos = box2.pos-box1.pos
    if not (getSeparatingPlane(r_pos, box1.axisX, box1, box2) or getSeparatingPlane(r_pos, box1.axisY, box1, box2) or
            getSeparatingPlane(r_pos, box1.axisZ, box1, box2) or getSeparatingPlane(r_pos, box2.axisX, box1, box2) or
            getSeparatingPlane(r_pos, box2.axisY, box1, box2) or getSeparatingPlane(r_pos, box2.axisZ, box1,box2) or
            getSeparatingPlane(r_pos, cross_product(box1.axisX, box2.axisX), box1, box2) or
            getSeparatingPlane(r_pos, cross_product(box1.axisX, box2.axisY), box1, box2) or
            getSeparatingPlane(r_pos, cross_product(box1.axisX, box2.axisZ), box1, box2) or
            getSeparatingPlane(r_pos, cross_product(box1.axisY, box2.axisX), box1, box2) or
            getSeparatingPlane (r_pos, cross_product(box1.axisY, box2.axisY), box1, box2) or
            getSeparatingPlane (r_pos, cross_product(box1.axisY, box2.axisZ), box1, box2) or
            getSeparatingPlane (r_pos, cross_product(box1.axisZ, box2.axisX), box1, box2) or
            getSeparatingPlane (r_pos, cross_product(box1.axisZ, box2.axisY), box1, box2) or
            getSeparatingPlane (r_pos, cross_product(box1.axisZ, box2.axisZ), box1, box2)):
        return True
    else:
        return False


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值