欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

3D空間中的AABB(軸向平行包圍盒, Aixe align bo

系統(tǒng) 2695 0

引言

??????????? 在 前面的一篇文章 中講述了怎樣通過(guò)模型的頂點(diǎn)來(lái)求的模型的包圍球,而且還講述了基本包圍體除了包圍球之外,還有AABB包圍盒。在這一章,將講述怎樣依據(jù)模型的坐標(biāo)求得它的AABB盒。




表示方法

? ? ? ? ? ?? AABB盒的表示方法有非常多,總結(jié)起來(lái)有例如以下的三種情況:

? ? ? ? ? ?? Max-min表示法:使用一個(gè)右上角和左下角的點(diǎn)來(lái)唯一的定義一個(gè)包圍體

? ? ? ? ? ?? Center-radious表示法:我們用center點(diǎn)來(lái)表示中點(diǎn),radious是一個(gè)數(shù)組,保存了包圍盒在x方向,y方向,z方向上的半徑。

? ? ? ? ? ??? Min-Width表示方法:我們用min來(lái)定義左下角的點(diǎn),使用width來(lái)保存在x,y,z方向上的長(zhǎng)度。

????????????? 不同的方法,他們的碰撞檢測(cè)算法也會(huì)有所不同,而且不同的表示方法也會(huì)適用在不同的情形下。所以,大家自己設(shè)計(jì)的時(shí)候,須要謹(jǐn)慎考慮。

????????????? 在本文中,將會(huì)使用的是Max-min表示方法,例如以下所看到的:

      class AABB

{

   ....

public:

    VECTOR3 max ;

   ?VECTOR3 min ;

};


    
??????????? 在這樣的表示方法之下,進(jìn)行碰撞檢測(cè)的代碼例如以下所看到的:

      bool AABB::isCollided(AABB* a)
{
	if(max.x < a->min.x || min.x > a->max.x) return false ;
	if(max.y < a->min.y || min.y > a->max.y) return false ;
	if(max.z < a->min.z || min.z > a->min.z) return false ;

	return true ;
}// end for isCollided
    



AABB盒構(gòu)造

??????????? 構(gòu)造AABB盒的方法有非常多種,有的非常easy,有的非常復(fù)雜,這里將介紹兩種主要的構(gòu)造方法,他們也非常的簡(jiǎn)單,easy掌握。

???????????? 第一種是固定大小的AABB盒,這樣的AABB盒在構(gòu)造完成之后,無(wú)論被包圍的物體怎么樣的旋轉(zhuǎn),都不須要在進(jìn)行又一次構(gòu)造了。

??????????? 另外一種是比較緊湊的一種,利用X,Y和Z軸向上最長(zhǎng)和最遠(yuǎn)的點(diǎn)來(lái)構(gòu)造一個(gè)AABB盒。



固定大小AABB盒

??????????? 正如上面說(shuō)的那樣,固定大小的AABB盒,它須要被包圍的物體,無(wú)論怎么旋轉(zhuǎn),都還在這個(gè)包圍體里面。所以,我們先為這個(gè)物體構(gòu)造一個(gè)包圍球體,然后在這個(gè)包圍球體的基礎(chǔ)上構(gòu)建一個(gè)AABB盒。這樣就行達(dá)到無(wú)論怎么旋轉(zhuǎn),都還在包圍體里面。

??????????? 只是,為這個(gè)物體構(gòu)建一個(gè)包圍球相同也可以滿足這種要求,所以,就有點(diǎn)雞肋了??墒牵谀承┫拗茥l件下,你無(wú)法使用包圍球,那么就行使用這個(gè)方案來(lái)構(gòu)建一個(gè)固定大小的AABB盒。

??????????? 這個(gè)算法的核心是怎樣構(gòu)建一個(gè)包圍球體,而這個(gè)算法我在前面一章中已經(jīng)講述了,就不再反復(fù),感興趣的讀者能夠去看博客中 3D空間包圍球(Bounding Sphere)的求法 的文章。

?????????? 在有了包圍球之后,我們通過(guò)例如以下的方法就行計(jì)算出固定大小的AABB盒了:

      void AABB::computeFixedAABB(Sphere *s)
{
	max.x = s->center.x + s->radious ;
	max.y = s->center.y + s->radious ;
	max.z = s->center.z + s->radious ;
	min.x = s->center.x - s->radious ;
	min.y = s->center.y - s->radious ;
	min.z = s->center.z - s->radious ;
}// end for computeFixedAABB

    



緊湊點(diǎn)的AABB盒

?????????? 這個(gè)AABB盒的構(gòu)造方法,是從頂點(diǎn)集中獲取X,Y和Z方向上最遠(yuǎn)的和近期的點(diǎn),然后利用他們來(lái)構(gòu)建一個(gè)AABB盒。這樣的方法也非常easy。我直接上代碼來(lái)給大家解說(shuō):

      void AABB::computeAABBFromOriginalPointSet(VECTOR3* vertices, unsigned int vertex_num)
{
	unsigned int minX_i = 0 , maxX_i = 0 ;
	extrameDistanceAlongDir(MAKE_VECTOR3(1,0,0), vertices, vertex_num, &minX_i, &maxX_i);
	min.x = vertices[minX_i].x ;
	max.x = vertices[maxX_i].x ;

	unsigned int minY_i = 0 , maxY_i = 0;
	extrameDistanceAlongDir(MAKE_VECTOR3(0,1,0),vertices, vertex_num, &minY_i, &maxY_i);
	min.y = vertices[minY_i].y ;
	max.y = vertices[maxY_i].y ;

	unsigned int minZ_i = 0 , maxZ_i = 0;
	extrameDistanceAlongDir(MAKE_VECTOR3(0,0,1),vertices, vertex_num, &minZ_i, &maxZ_i);
	min.z = vertices[minZ_i].z ;
	max.z = vertices[maxZ_i].z ;
}// end for computeAABBFromOriginalPointSet

void AABB::extrameDistanceAlongDir(VECTOR3 dir, VECTOR3* vertices, unsigned int vertex_num, unsigned int* min, unsigned int*max)
{
	float maxProj = FLT_MIN , minProj = FLT_MAX ;
	for(unsigned int i = 0 ; i < vertex_num ; i ++)
	{
		float proj = 0 ;
		Vec3Dot(proj, vertices[i], dir);

		if(proj > maxProj)
		{
			maxProj = proj ;
			*max = i ;
		}

		if(proj < minProj)
		{
			minProj = proj ;
			*min = i ;
		}
	}// end for
}// end for extrameDistanceAlongDir
    

?????????? 上面一共同擁有兩個(gè)函數(shù),第一個(gè)函數(shù)就是給用戶調(diào)用的計(jì)算AABB盒的方法。用戶僅僅須要將模型的頂點(diǎn)集傳遞進(jìn)來(lái)就可以。

?????????? 第二個(gè)函數(shù),是獲取在指定的軸向上,哪個(gè)點(diǎn)在這個(gè)軸向上的投影是最長(zhǎng)的和最短的。這個(gè)函數(shù)非常easy,僅僅須要調(diào)用一個(gè)點(diǎn)積Dot運(yùn)算就行求出。

????????? 當(dāng)求出了在X,Y和Z軸向上投影最長(zhǎng)和最短的6個(gè)點(diǎn)之后,我們就分別取他們相應(yīng)的軸向上的坐標(biāo)值來(lái)構(gòu)成Max和min,這樣一個(gè)AABB盒就構(gòu)造完成了。是不是非常easy??




AABB類

????????? 以下是AABB的完整類:

      //--------------------------------------------------------------------------------------------------
// declaration	: Copyright (c), by XJ , 2014 . All right reserved .
// brief		: This file will define the Axie aligned bounding box.
// author		: XJ
// date			: 2014 / 6 / 22
// file			: AABB.h
// version		: 1.0
//---------------------------------------------------------------------------------------------------
#pragma once
#include"XJMath.h"
#include"Sphere.h"

namespace XJCollision
{
	/**
	* brief	: We use the Max-min representation
	*/
	class AABB
	{
	public:
		AABB();
		AABB(VECTOR3 min, VECTOR3 max);

	public:
		/**
		* Compute the fixed AABB
		*/
		void computeFixedAABB(Sphere* s);

		/**
		* Compute the AABB from the original point set
		*/
		void computeAABBFromOriginalPointSet(VECTOR3 *vertices, unsigned int vertex_num);

		/**
		* Collision Detection between two AABB
		*/
		bool isCollided(AABB* a);

	private:
		/**
		* Compute the least and most distance along the specific direction
		*/
		void extrameDistanceAlongDir(VECTOR3 dir, VECTOR3 * vertices, unsigned int vertex_num, unsigned int * min, unsigned int * max);

	public:
		VECTOR3 max ;
		VECTOR3 min ;
	};
};
    

      #include"AABB.h"
#include<cmath>
#include<float.h>
using namespace XJCollision ;

AABB::AABB()
	:max(),
	min()
{

}

AABB::AABB(VECTOR3 _max, VECTOR3 _min)
{
	max.x = _max.x ; max.y = _max.y ; max.z = _max.z ;
	min.x = _min.x ; min.y = _min.y ; min.z = _min.z ;
}

void AABB::computeFixedAABB(Sphere *s)
{
	max.x = s->center.x + s->radious ;
	max.y = s->center.y + s->radious ;
	max.z = s->center.z + s->radious ;
	min.x = s->center.x - s->radious ;
	min.y = s->center.y - s->radious ;
	min.z = s->center.z - s->radious ;
}// end for computeFixedAABB

void AABB::computeAABBFromOriginalPointSet(VECTOR3* vertices, unsigned int vertex_num)
{
	unsigned int minX_i = 0 , maxX_i = 0 ;
	extrameDistanceAlongDir(MAKE_VECTOR3(1,0,0), vertices, vertex_num, &minX_i, &maxX_i);
	min.x = vertices[minX_i].x ;
	max.x = vertices[maxX_i].x ;

	unsigned int minY_i = 0 , maxY_i = 0;
	extrameDistanceAlongDir(MAKE_VECTOR3(0,1,0),vertices, vertex_num, &minY_i, &maxY_i);
	min.y = vertices[minY_i].y ;
	max.y = vertices[maxY_i].y ;

	unsigned int minZ_i = 0 , maxZ_i = 0;
	extrameDistanceAlongDir(MAKE_VECTOR3(0,0,1),vertices, vertex_num, &minZ_i, &maxZ_i);
	min.z = vertices[minZ_i].z ;
	max.z = vertices[maxZ_i].z ;
}// end for computeAABBFromOriginalPointSet

void AABB::extrameDistanceAlongDir(VECTOR3 dir, VECTOR3* vertices, unsigned int vertex_num, unsigned int* min, unsigned int*max)
{
	float maxProj = FLT_MIN , minProj = FLT_MAX ;
	for(unsigned int i = 0 ; i < vertex_num ; i ++)
	{
		float proj = 0 ;
		Vec3Dot(proj, vertices[i], dir);

		if(proj > maxProj)
		{
			maxProj = proj ;
			*max = i ;
		}

		if(proj < minProj)
		{
			minProj = proj ;
			*min = i ;
		}
	}// end for
}// end for extrameDistanceAlongDir

bool AABB::isCollided(AABB* a)
{
	if(max.x < a->min.x || min.x > a->max.x) return false ;
	if(max.y < a->min.y || min.y > a->max.y) return false ;
	if(max.z < a->min.z || min.z > a->min.z) return false ;

	return true ;
}// end for isCollided
    

程序?qū)嵗?

??????????? 以下的兩種圖,各自是使用了第一種和另外一種計(jì)算方法計(jì)算出來(lái)的包圍盒:

?

3D空間中的AABB(軸向平行包圍盒, Aixe align bounding box)的求法


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦?。。?/p>

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 日韩欧美在线播放 | 在线视频中文字幕乱人伦 | 91看片淫黄大片在看 | 久久久久久国产精品视频 | 国内自拍视频在线观看 | 92香蕉视频 | 99视频在线观看精品 | av网站观看 | 日韩三极 | 久久久国产99久久国产一 | 国产精品成人一区二区三区 | 亚洲美女一区二区三区 | 亚洲国产精品久久 | 曰本一级毛片免费 | 中文字幕免费在线观看动作大片 | 亚洲天堂日本 | 777xacom| 国产精品一区二区三区免费 | 激情九月 | 一级欧美一级日韩 | 欧美激情综合色综合啪啪五月 | 国产成人99| 色蜜桃网 | 国产一区久久精品 | 天天射天 | 好大好硬好长好爽a网站 | 国产成人啪精品视频免费网站软件 | 精品久久久久区二区8888 | 欧美性野久久久久久久久 | 欧美成人精品一区二区三区 | 午夜影视大全 | 国产高清在线精品一区二区三区 | 欧美日韩午夜精品 | 一区二区三区在线免费观看 | 午夜日韩 | 中国黄色一级生活片 | 国产国语一级a毛片高清视频 | av网站在线免费观看 | 午夜精品 | 婷婷久久精品 | 亚洲精品成A人在线观看拍拍拍 |