青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

life02

  C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
  197 隨筆 :: 3 文章 :: 37 評論 :: 0 Trackbacks

http://www.cnblogs.com/cgwolver/archive/2009/03/26/1257611.html
假定在右手坐標系中的三角形3點坐標為A,B,C,判斷P是否在ABC之內(nèi)

( 主要來自 3D引擎研發(fā)QQ群(38224573 )的各位朋友的討論 ,我僅僅算做個總結(jié)吧,特別感謝各位朋友的熱情支持。 )

方法1:三個Perplane的方法

           設(shè)AB,BC,AC邊上的垂直平面為Perplane[3],垂直朝向內(nèi)側(cè)的法向為n[3]

          1)先根據(jù)任意兩邊叉出法向N

               N = AB.CrossProduct(AC);

               N.Normalize();

               D = A.DotProduct( N );

          2)如果P在三角形所在平面之外,可直接判定不在平面之內(nèi)( 假定方程為 ax+by+cz+d = 0 )

               if( P.DotProduct( N ) + D > 0 ) return false;

          3)然后法向和各邊叉出垂直平面的法向

               n[0] = N.CrossProduct(AB); //朝向內(nèi)側(cè)

               n[0].Normalize();

               Perplane[0].dist = A.DotProduct(n[0]);

               Perplane[0].normal = n[0];

               同樣方法求得Perplane[1],Perlane[2];

          3)因為三個Perplane都朝向三角形內(nèi)側(cè),P在三角形內(nèi)的條件是同時在三個Perplane前面;如果給定點P在任意一個垂直平面之后,那么可判定P在三角形外部

               for( int i = 0;i<3;j++ )

               {

                    if( P.DotProduct( Perplane[i].normal ) + Perplane[i].dist < 0 )

                         return false;

               }

               return true;//如果P沒有在任意一條邊的外面,可判斷定在三角形之內(nèi),當然包括在邊上的情況

方法2:三個部分面積與總面積相等的方法

          S(PAB) + S(PAC) + S( PBC) = S(ABC) 則判定在三角形之內(nèi)

          用矢量代數(shù)方法計算三角形的面積為

               S = 1/2*|a|*|b|*sin(theta)

                  = 1/2*|a|*|b|*sqrt(1-cos^2(theta))

                  = 1/2*|a|*|b|*sqrt(1- (a.DotProduct(b)/(|a|*|b|))^2);

               另一種計算面積的方法是 S = 1/2*|a.CrossProduct(b)|

               比較一下,發(fā)現(xiàn)后者的精確度和效率都高于前者,因為前者需要開方和求矢量長度,矢量長度相當于一次點乘,三個點乘加一個開方,顯然不如

               后者一次叉乘加一次矢量長度(注,一次叉乘計算相當于2次點乘,一次矢量長度計算相當于一次點乘),后者又對又快。

               

               S(ABC)  = AB.CrossProduct(AC);//*0.5;

               S(PAB)  = PA.CrossProduct(PB);//*0.5;

               S(PBC)  = PB.CrossProduct(PC);//*0.5;

               S(PAC)  = PC.CrossProduct(PA);//*0.5;

               if( S(PAB) + S(PBC) + S(PAC) == S(ABC)  )

                    return true;

               return false;

         

        另一種計算三角形面積的矢量方法是 1/2*a.CrossProdcuct(b) ,CrossProduct = ( y1*z2 - y2*z1 , x1*z2 - x2*z1, x1*y2 - x2*z1 )

               可以看到CrossProduct 的計算要比DotProduct多3個乘法計算,效率沒有上面的方法高


方法3:三個向量歸一化后相加為0

        這個方法很怪異,發(fā)現(xiàn)自http://flipcode.spaces.live.com/blog/cns!8e578e7901a88369!903.entry 下面的一個回帖

                 
              

          如上圖三角形ABC,P為AB外側(cè)一點,N1,N2,N3 分別為BP,AP,CP的歸一化矢量;NM為N1,N2夾角的角平分線

          可以看出角A-P-B是三角形內(nèi)角,必然小于180度,那么角N1-P-N2等于A-P-B;NM是N1-P-N2的角平分線,那么角B-P-N等于角N-P-A,而CPN必然小于其中一個,

          即小于180/2 = 90度。結(jié)論是角N1,N2的合矢量方向與N3的夾角為銳角。所以N1,N2,N3的合向量模大于1.

          這里注意,N3不一定在N1,N2之間,不能假定N2-P-N3 和N3-P-N1這兩個角一定是銳角

          同樣可以推導(dǎo)出如果P在三角形內(nèi),N1+N2+N3必然小于0;若N1+N2+N3 = 0則P在三角形的邊上。

          有沒有更簡單的推導(dǎo)方法?

         

          這個方法看起來很精巧,但是善于優(yōu)化的朋友會立刻發(fā)現(xiàn),三個矢量歸一化,需要三個開方。迭代式開方太慢了,而快速開方有的時候又不滿足精度要求。

                 

 方法4:重心坐標之和為1

         {

               BaryCenter = ( S(PAB)/S(PABC),S(PBC)/S(PABC),S(PAC)/S(PABC)) // 點P在三角形內(nèi)的重心坐標

         

               if( BaryCenter.x + BaryCenter.y + BaryCenter.z >0.f )

                    return false

               return true;

          }

          其中S(PAB),S(ABC),S(PBC),S(PBC) 用上述的方法二種提到的計算三角形面積方法計算。

綜合比較

     方法1必須求叉乘,雖然可以通過首先排除不在平面內(nèi)的點,但是后面仍要求三個叉乘和3個點乘(當然還可排除法優(yōu)化)

     方法2看起來之需要求4個點乘,如果用叉乘方法計算面積,可能會導(dǎo)致效率低下

     方法3是看起來是最精巧的方法,但是效率也不能保證...3個開方

     方法4和方法2的效率差不多

 

本文來自CSDN博客,轉(zhuǎn)載請標明出處:http://blog.csdn.net/boyzk2008/archive/2009/08/07/4421106.aspx

posted on 2009-09-25 10:22 life02 閱讀(1663) 評論(8)  編輯 收藏 引用 所屬分類: 游戲開發(fā)

評論

# re: 如何判斷一點在三角形內(nèi)(轉(zhuǎn)) 2009-10-16 02:54 路人
有一個經(jīng)典的封閉多邊形判斷是否內(nèi)部的方法,
從該點引一條射線出來, 與多邊形交點為奇數(shù)的為內(nèi)部, 偶數(shù)外部  回復(fù)  更多評論
  

# re: 如何判斷一點在三角形內(nèi)(轉(zhuǎn)) 2009-10-16 14:29 溪流
@路人
這個說法好不嚴謹,這條射線與多邊形頂點相交、與邊重合的情況  回復(fù)  更多評論
  

# re: 如何判斷一點在三角形內(nèi)(轉(zhuǎn)) 2009-10-16 23:30 路人
當然前面提出的射線法需要預(yù)先排除一些內(nèi)容, 這在計算交點的過程中可以巧妙達到:)

因為三角形不可能是凹多邊形,
一般取三角形頂點到該點的方向做為射線方向,這樣交點如包括自己就表明該點在邊上,0個交點, 在外部, 1個交點, 在內(nèi)部   回復(fù)  更多評論
  

# re: 如何判斷一點在三角形內(nèi)(轉(zhuǎn)) 2010-07-06 00:27 kita
引用" if( P.DotProduct( N ) + D > 0 ) return false;

這個應(yīng)該是 Dot(P,N) - D == 0 吧



引用" n[0] = N.CrossProduct(AB); //朝向內(nèi)側(cè)

這個得出來的成績應(yīng)該是外側(cè)吧!   回復(fù)  更多評論
  

# 繼續(xù)研究下去發(fā)現(xiàn)更多問題!!! 2010-07-06 00:53 kita
S(ABC) = AB.CrossProduct(AC);//*0.5;

這樣算是錯的


應(yīng)該是 S_ABC = |Coss(AB,AC)| 絕對值不能少
也就是 S_ABC = Coss(AB,AC).Length(); //C#

這樣算程序才得出正確結(jié)果.
  回復(fù)  更多評論
  

# re: 如何判斷一點在三角形內(nèi)(轉(zhuǎn)) 2010-07-06 00:54 kita
private Boolean InTriangleByS(Vector3 A, Vector3 B, Vector3 C, Vector3 P)
{
Vector3 AB = A - B;
Vector3 CA = C - A;

Vector3 PA = P - A;
Vector3 PB = P - B;
Vector3 PC = P - C;

float SABC = Vector3.Cross(AB, CA).Length();//*0.5;

float SPAB = Vector3.Cross(PA, PB).Length();//*0.5;

float SPBC = Vector3.Cross(PB, PC).Length();//*0.5;

float SPAC = Vector3.Cross(PC, PA).Length();//*0.5;

if (SPAB + SPBC + SPAC == SABC)
return true;

return false;
}

private Boolean InTriangleByPlane(Vector3 A, Vector3 B, Vector3 C, Vector3 P)
{
Vector3 ab = A - B;
Vector3 ca = C - A;
Vector3 bc = B - C;

Vector3 N = Vector3.Cross(ab, bc);
N.Normalize();

float D = Vector3.Dot(A, N);
float D_PN = Vector3.Dot(P, N);


if (Math.Round(D_PN - D, 2) != 0)
{
return false;
}

Vector3[] p_n = new Vector3[3];

p_n[0] = Vector3.Cross(N, ab);
//p_n[0].Normalize();

p_n[1] = Vector3.Cross(N, bc);
//p_n[1].Normalize();

p_n[2] = Vector3.Cross(N, ca);
//p_n[2].Normalize();

Plane[] p = new Plane[3];

p[0].D = Vector3.Dot(A, p_n[0]);
//p[0].Normal = p_n[0];

p[1].D = Vector3.Dot(B, p_n[1]);
//p[1].Normal = p_n[1];

p[2].D = Vector3.Dot(C, p_n[2]);
//p[2].Normal = p_n[2];

for (int i = 0; i < 3; i++)
{
float D_PpN = Vector3.Dot(P, p[i].Normal);
if (D_PpN - p[i].D > 0)
{
return false;
}
}

return true;
}  回復(fù)  更多評論
  

# re: 如何判斷一點在三角形內(nèi)(轉(zhuǎn)) 2010-07-06 01:03 kita
關(guān)于效率 各執(zhí)行 10000次

適用Plane 的求法使用時間是 面積的 1/2   回復(fù)  更多評論
  

# re: 如何判斷一點在三角形內(nèi)(轉(zhuǎn)) 2010-07-06 01:35 kita
引用 " 同樣可以推導(dǎo)出如果P在三角形內(nèi),N1+N2+N3必然小于0;若N1+N2+N3 = 0則P在三角形的邊上。

按原圖
假設(shè) P 在 三角形邊上

則 N1 + N2 = (0,0,0)

N3 的長度為 1 (歸一化向量長度必為1 )

N1 + N2 + N3 怎么加也不可能得出 0 , 必然是 長度為1 的向量。

因此 N1+N2+N3 少于 1 為在三角內(nèi) 大于1 為三角外。

但此方法的確是最慢的  回復(fù)  更多評論
  


只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美1区视频| 亚洲国产精品www| 亚洲女优在线| 国产精品欧美日韩| 久久精品视频在线看| 性欧美大战久久久久久久免费观看| 欧美午夜一区二区| 性18欧美另类| 欧美影院成人| 亚洲国产合集| 一本色道久久99精品综合| 欧美性淫爽ww久久久久无| 性xx色xx综合久久久xx| 久久久www成人免费无遮挡大片| 极品尤物久久久av免费看| 欧美激情久久久久| 欧美日韩久久精品| 久久精品av麻豆的观看方式| 久久蜜桃av一区精品变态类天堂| 亚洲韩国精品一区| 亚洲免费成人av| 国产三级欧美三级| 欧美18av| 国产精品一区二区男女羞羞无遮挡 | 欧美激情第三页| 欧美午夜a级限制福利片| 久久精品国产v日韩v亚洲| 久久青青草综合| 一道本一区二区| 欧美综合二区| 一本色道久久综合狠狠躁篇怎么玩| 在线综合欧美| 亚洲国产小视频在线观看| 99在线热播精品免费| 激情久久五月| 亚洲深夜福利在线| 亚洲电影有码| 校园春色国产精品| 亚洲一区二区在线| 久久视频在线免费观看| 午夜精品亚洲| 欧美日韩不卡| 欧美激情在线观看| 国产日韩精品电影| 亚洲美女视频在线观看| 激情一区二区| 亚洲一区二区三区高清不卡| 99re亚洲国产精品| 久久视频国产精品免费视频在线| 欧美一进一出视频| 欧美日韩国产小视频| 亚洲二区免费| 在线日韩av片| 久久激情五月婷婷| 久久久久久久一区二区三区| 欧美日韩在线一区二区| 亚洲国产高清高潮精品美女| 在线观看91精品国产入口| 亚洲女人小视频在线观看| 亚洲特级毛片| 欧美视频日韩| 日韩一级片网址| 99精品欧美一区二区三区| 牛牛精品成人免费视频| 欧美成在线观看| 亚洲国产日韩在线一区模特| 久久精品噜噜噜成人av农村| 久久久www| 国语精品一区| 久久久久一区二区| 欧美成人免费在线| 亚洲高清免费在线| 欧美成人影音| 亚洲日本一区二区三区| 一区二区精品在线| 国产精品v日韩精品| 亚洲一区在线看| 久久国产精品第一页| 国内外成人免费激情在线视频 | 91久久综合亚洲鲁鲁五月天| 91久久夜色精品国产九色| 免费不卡在线视频| 日韩亚洲精品视频| 香港久久久电影| 黑人中文字幕一区二区三区| 久久深夜福利| 99国产成+人+综合+亚洲欧美| 亚洲一区免费| 黄色成人av网| 欧美精品首页| 亚洲欧美日韩国产精品| 免费视频最近日韩| 一本久久知道综合久久| 国产精品视频精品| 久久久天天操| 亚洲人成人99网站| 欧美一区二区三区四区视频| 国外视频精品毛片| 欧美精品一区二| 亚洲欧美日韩在线一区| 女人香蕉久久**毛片精品| 亚洲视频在线免费观看| 国产日韩精品在线播放| 欧美黄色片免费观看| 亚洲专区一区| 欧美成人性网| 欧美在线不卡| 亚洲精品美女在线| 国产日韩欧美黄色| 欧美激情中文不卡| 久久久7777| 一本色道久久综合亚洲精品婷婷| 久久激情视频免费观看| 亚洲裸体视频| 国内自拍一区| 国产精品v亚洲精品v日韩精品 | 亚洲精品乱码久久久久久蜜桃麻豆| 午夜精品99久久免费| 亚洲国产精品www| 国产精品一区二区你懂得| 欧美freesex8一10精品| 久久爱www.| 亚洲视频综合| 亚洲精品日韩在线观看| 欧美暴力喷水在线| 久久精品最新地址| 亚洲一区三区电影在线观看| 亚洲欧洲一二三| 国产自产2019最新不卡| 国产精品久久久久久av下载红粉| 老牛影视一区二区三区| 欧美中文日韩| 亚洲午夜小视频| 9人人澡人人爽人人精品| 欧美国产综合一区二区| 久久综合狠狠综合久久综合88 | **网站欧美大片在线观看| 国产农村妇女毛片精品久久麻豆| 欧美色图五月天| 欧美日韩国产成人在线| 美脚丝袜一区二区三区在线观看 | 米奇777在线欧美播放| 久久精品国产99精品国产亚洲性色| 亚洲少妇自拍| 一区二区三区产品免费精品久久75| 91久久久精品| 亚洲乱码国产乱码精品精天堂| 亚洲国产高清aⅴ视频| 亚洲第一级黄色片| 亚洲国产精品成人精品| 亚洲国产精品久久久久| 亚洲激情网址| 日韩小视频在线观看| 日韩视频久久| 中文欧美日韩| 国产精品99久久久久久宅男| 在线亚洲+欧美+日本专区| 一本一本大道香蕉久在线精品| 一区二区三区国产精华| 亚洲天堂激情| 欧美亚洲视频一区二区| 久久国产一区二区| 久久久久久黄| 欧美成人第一页| 欧美日韩在线视频一区二区| 国产精品久久久久久av下载红粉 | 麻豆国产va免费精品高清在线| 免费成人性网站| 欧美精品一区二区三区在线播放 | 欧美电影资源| 欧美另类在线播放| 国产精品久久国产精麻豆99网站| 国产日韩欧美在线播放不卡| 黄色成人在线网站| 亚洲精品日韩精品| 亚洲欧美综合网| 鲁大师影院一区二区三区| 亚洲国产精品一区制服丝袜| 99精品视频一区| 久久精品国产一区二区电影| 欧美黄色免费| 国产三级精品三级| 日韩视频―中文字幕| 欧美综合77777色婷婷| 欧美激情91| 亚洲一区二区伦理| 欧美成人国产| 国产午夜亚洲精品不卡| 91久久精品日日躁夜夜躁欧美| 亚洲欧美另类中文字幕| 蜜臀久久久99精品久久久久久 | 亚洲午夜精品一区二区三区他趣 | 亚洲精品久久久久久久久久久| 亚洲一区二区三区精品在线观看| 久久综合色播五月| 国产精品专区第二| 一本大道久久a久久精品综合| 久久婷婷蜜乳一本欲蜜臀| 亚洲最新色图| 欧美成人a视频|