快速相交检测:平面与包围盒

2024-06-16 22:08

本文主要是介绍快速相交检测:平面与包围盒,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

快速相交检测:平面与包围盒

  • 1.前言
  • 2.数学背景
  • 3.计算原理
  • 4.代码

1.前言

   在游戏等实时性要求高的三维程序中,相交检测是一项及其基础又重要的技术,大佬们相继提出各种检测技术。
  当然大多数人的实现方式可能 (确信)是将包围盒的8个点分别带入平面检测,这将要做8组点积。
  今天我来介绍其中一项比较快速的检测方法,在略去相交和内部的判断后可以直接降到四次点积,当然如果使用的是AABB则会变成一次点积,目前我是按照OBB的方式来算的。

2.数学背景

平面方程形式: A x + B y + C z + D = 0 Ax+By+Cz+D =0 Ax+By+Cz+D=0
对于坐标 P ( x 0 , y 0 , z 0 ) P(x_0,y_0,z_0) P(x0,y0,z0)
检验其是否在平面内,可以直接带入平面方程
A x 0 + B y 0 + C z 0 + D Ax_0+By_0+Cz_0+D Ax0+By0+Cz0+D

  • 若结果>0,则在平面外部。
  • 若结果=0,则在正好在平面上。
  • 若结果<0,则在平面内部。

什么?你问我平面还分内外?
这个我也无法解释,毕竟我只是一只鸽子
目前我个人来说,习惯性将平面法向量指向的那一侧称呼为外部,法向量负方向一侧称为内部

3.计算原理

   最重要的步骤是找到包围盒的n顶点和p顶点。
在这里插入图片描述

  • 如果n顶点位于平面外部,则直接返回包围盒在平面外。
  • 如果n顶点位于平面内部,p顶点位于平面外部,返回包围盒与平面相交。
  • 如果n顶点位于平面内部,p顶点位于平面内部,返回包围盒在平面内。

那么n、p顶点如何寻找呢,通过将平面法向量与包围盒的轴方向进行点积,判断点积结果的正负来寻找。

4.代码

ok,按照惯例先放出结果图

  • 0代表在外部
  • 1代表相交
  • -1代表在内部

测试用例包围盒为在点(0,0,0),长为(1,1,1),第一个轴方向为(1,0,0),第二个轴方向为(0,1,0),第二个轴方向为(0,0,1),对就是xyz轴方向
第一个是在点(2,2,2),法向量为(-1,-1,-1)的平面测试
第二个是在点(0.5,0.5,0.5),法向量为(-1,-1,-1)的平面测试
第三个是在点(-2,-2,-2),法向量为(-1,-1,-1)的平面测试
在这里插入图片描述

#include "pch.h"#include <iostream>using namespace std;class vec3
{
public:float x, y, z;
};
class box
{
public:box(vec3 dx,vec3 dy,vec3 dz,vec3 l,vec3 o):dX(dx),dY(dy),dZ(dz),len(l),origin(o){}vec3 dX, dY, dZ;vec3 len;vec3 origin;};float dot(vec3 a, vec3 b)
{return (a.x * b.x + a.y * b.y + a.z * b.z);
}class plane
{
public:plane(vec3 v,vec3 n){a = n.x;b = n.y;c = n.z;d = -(dot(v,n));}public:float check(vec3 x){return (x.x * a + x.y * b + x.z * c + d);}
public:union {struct{float a, b, c;};vec3 n;};float d;};vec3 operator+ (vec3 const& _Left, vec3 const& _Right) noexcept
{return (vec3{ _Left.x + _Right.x , _Left.y + _Right.y , _Left.z + _Right.z });
}vec3 operator* (float _Left, vec3 const& _Right) noexcept
{return (vec3{ _Left* _Right.x , _Left* _Right.y , _Left* _Right.z });
}int check(box _box,plane _plane)
{auto res1 = dot(_plane.n,_box.dX);auto res2 = dot(_plane.n, _box.dY);auto res3 = dot(_plane.n, _box.dZ);char mask_n = 0 | (res1 >= 0 ? 0 : 1) | (res2 >= 0 ? 0 : 2) | (res3 >= 0 ? 0 : 4);vec3 _n = _box.origin;if (mask_n & 1){_n = _n + (_box.len.x * _box.dX);}if (mask_n & 2){_n = _n + (_box.len.y * _box.dY);}if (mask_n & 4){_n = _n + (_box.len.z * _box.dZ);}if (_plane.check(_n) < 0.0){char mask_p = ~mask_n;vec3 _p = _box.origin;if (mask_p & 1){_p = _p + (_box.len.x * _box.dX);}if (mask_p & 2){_p = _p + (_box.len.y * _box.dY);}if (mask_p & 4){_p = _p + (_box.len.z * _box.dZ);}if (_plane.check(_p) < 0.0){// insidereturn (-1);}else{// intersectreturn (1);}}// outside;return 0;
}int main()
{plane p1({ 2,2,2 }, { -1,-1,-1 });plane p2({ 0.5,0.5,0.5 }, { -1,-1,-1 });plane p3({ -2,-2,-2 }, { -1,-1,-1 });box _box({1,0,0},{ 0,1,0},{ 0,0,1 },{1,1,1},{0,0,0});std::cout << check(_box, p1) << std::endl;std::cout << check(_box, p2) << std::endl;std::cout << check(_box, p3) << std::endl;return 0;
}

这篇关于快速相交检测:平面与包围盒的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1067682

相关文章

乐鑫 Matter 技术体验日|快速落地 Matter 产品,引领智能家居生态新发展

随着 Matter 协议的推广和普及,智能家居行业正迎来新的发展机遇,众多厂商纷纷投身于 Matter 产品的研发与验证。然而,开发者普遍面临技术门槛高、认证流程繁琐、生产管理复杂等诸多挑战。  乐鑫信息科技 (688018.SH) 凭借深厚的研发实力与行业洞察力,推出了全面的 Matter 解决方案,包含基于乐鑫 SoC 的 Matter 硬件平台、基于开源 ESP-Matter SDK 的一

基于CTPN(tensorflow)+CRNN(pytorch)+CTC的不定长文本检测和识别

转发来源:https://swift.ctolib.com/ooooverflow-chinese-ocr.html chinese-ocr 基于CTPN(tensorflow)+CRNN(pytorch)+CTC的不定长文本检测和识别 环境部署 sh setup.sh 使用环境: python 3.6 + tensorflow 1.10 +pytorch 0.4.1 注:CPU环境

LVGL快速入门笔记

目录 一、基础知识 1. 基础对象(lv_obj) 2. 基础对象的大小(size) 3. 基础对象的位置(position) 3.1 直接设置方式 3.2 参照父对象对齐 3.3 获取位置 4. 基础对象的盒子模型(border-box) 5. 基础对象的样式(styles) 5.1 样式的状态和部分 5.1.1 对象可以处于以下状态States的组合: 5.1.2 对象

基于深度学习的轮廓检测

基于深度学习的轮廓检测 轮廓检测是计算机视觉中的一项关键任务,旨在识别图像中物体的边界或轮廓。传统的轮廓检测方法如Canny边缘检测和Sobel算子依赖于梯度计算和阈值分割。而基于深度学习的方法通过训练神经网络来自动学习图像中的轮廓特征,能够在复杂背景和噪声条件下实现更精确和鲁棒的检测效果。 深度学习在轮廓检测中的优势 自动特征提取:深度学习模型能够自动从数据中学习多层次的特征表示,而不需要

自动驾驶---Perception之Lidar点云3D检测

1 背景         Lidar点云技术的出现是基于摄影测量技术的发展、计算机及高新技术的推动以及全球定位系统和惯性导航系统的发展,使得通过激光束获取高精度的三维数据成为可能。随着技术的不断进步和应用领域的拓展,Lidar点云技术将在测绘、遥感、环境监测、机器人等领域发挥越来越重要的作用。         目前全球范围内纯视觉方案的车企主要包括特斯拉和集越,在达到同等性能的前提下,纯视觉方

算法6— 判断两个链表是否相交

问题: 给出两个单向链表的头指针,比如h1、h2,判断链表是否相交,如果不相交返回NULL;如果相交,返回指向第一个相交节点的指针。时间复杂度控制在O(n)。 分析: 如果两单向链表相交的话,一定是Y型相交,不可能出现X型,弄清楚这点后接下来的工作就是: (1)先找到h1,h2的最后一个节点L1和L2,同时记录节点数量a,b;(这里假设 a > b) (2)判断最后一个节点是否相同

【Spring】Spring Boot 快速入门

📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️ 🙏小杨水平有限,欢迎各位大佬指点,相互学习进步! 小杨近些在学习人工智能方面的知识,发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一

YOLOv9摄像头或视频实时检测

1、下载yolov9的项目 地址:YOLOv9 2、使用下面代码进行检测 import torchimport cv2from models.experimental import attempt_loadfrom utils.general import non_max_suppression, scale_boxesfrom utils.plots import plot_o

Sublime Text 快速折叠CSS代码到一行

快速折叠CSS代码到一行 1.使用HTML/CSS/JS Prettify或者CSScomb美化代码 2.使用Alt+F3特征选取,删除下图中所有的特征空格 3.使用Ctrl+Shift+M选取括号里的内容,再使用一次Ctrl+Shift+M将大括号也一起选中。 4.使用Ctr+J折叠代码 5.Home键 6.Backspace键

一篇文章带你快速入门java

文章目录 一、一个简单的java代码1.1 Java程序的结构由三个不成组成:1.2 运行java程序1.3 JDK,JRE,JVM之间的关系?(面试题)1.4 标识符1.5 注释1.6 关键字 一、一个简单的java代码 public class HelloJava {public static void main(String[] args) {System.out.