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

天行健 君子當自強而不息

幾何檢測(4)

新建網頁 1

 

球和平面的相交性檢測

球和平面的靜態檢測相對容易一些,可以用公式12.14來計算球心到平面的距離。如果距離小于球半徑,那么它們相交。實際上還能作一種更靈活的檢測,這種檢測把相交分為球完全在平面正面,完全在背面,跨平面等三種情況。仔細分析程序清單13.2

    Listing 13.2: Determining which side of a plane a sphere is on
   
   
// Given a sphere and plane, determine which side of the plane
    // the sphere is on.
    //
    // Return values:
    //
    // < 0 Sphere is completely on the back
    // > 0 Sphere is completely on the front
    // 0 Sphere straddles plane
   
int classifySpherePlane(
      
const Vector3 &planeNormal, // must be normalized
   
  float planeD, // p * planeNormal = planeD
   
  const Vector3 &sphereCenter, // center of sphere
   
  float sphereRadius // radius of sphere
   

    {
      
// Compute distance from center of sphere to the plane
   
  float d = planeNormal * sphereCenter – planeD;
   
      
// Completely on the front side?
   
  if (d >= sphereRadius) 
        
return +1;
   
      
// Completely on the back side?
   
  if (d <= –sphereRadius) 
        
return –1;
   
      
// Sphere intersects the plane
   
  return 0;
    }

動態檢測要稍微復雜一些。設平面為靜止的,球作所有的相對位移。

平面的定義方式一如既往,用標準形式p . n = d,n為單位向量。球由半徑r和初始球心位置c定義。球的位移,由單位向量d指明方向,L代表位移的距離。t從0變化到L,用直線方程c+td計算球心的運動軌跡。如圖13.13所示:

不管在平面上的哪一點上發生相交,在球上的相交點總是固定的,認識到這一點能大大簡化問題。用c-rn來計算交點,如圖13.14所示:

現在我們知道了球上的相交點,就可以利用射線與平面相交性檢測的方法,替換掉公式13.6中的p0,得到公式13.9

射線和三角形的相交性檢測

在圖形學和計算幾何中射線與三角形的相交性檢測是非常重要的。因為缺乏射線和復雜物體間相交性檢測的方法,我們通常用三角網格代表(或至少是近似代表)物體表面,再作射線和三角網格的相交性檢測。第一步是計算射線和包含該三角形的平面的交點,第二步是通過計算交點的重心坐標,來判斷它是否在三角形中。

為了使測試效率盡可能高,要使用下列技巧:

(1)在檢測中盡可能地返回負值(沒有相交),這稱作"提前結束(early out)"

(2)盡可能地延遲昂貴的數學運算,如除法。有兩個原因:第一,如果并不需要昂貴運算的結果,比如說遇到了提前結束的情況,那么執行這些運算的時間就白白浪費了。第二,它給了編譯器更多的空間以利用現代處理器的指令管道的優點。在準備除法運算時,它產生執行其他測試的代碼(可能導致提前結束)。所以,在執行期間,如果確實需要除法運算的結果,該結果可能已經被計算出來,或至少已經部分被計算出來了。

(3)只檢測與三角形正面的相交,這幾乎可以節省一半的檢測時間。

    // Ray-triangle intersection test.
    //
    // Algorithm from Didier Badouel, Graphics Gems I, pp 390-393
   
float rayTriangleIntersect(
        
const Vector3 &rayOrg,        // origin of the ray
   
    const Vector3 &rayDelta,    // ray length and direction
   
    const Vector3 &p0,            // triangle vertices
   
    const Vector3 &p1,            // .
   
    const Vector3 &p2,            // .
   
    float minT)                    // closest intersection found so far. (Start with 1.0)
   
{
        
// We'll return this huge number if no intersection is detected
   
    const float kNoIntersection = 1e30f;
   
        
// Compute clockwise edge vectors.
   
    Vector3 e1 = p1 – p0;
        Vector3 e2 = p2 – p1;
   
        
// Compute surface normal. (Unnormalized)
   
        Vector3 n = crossProduct(e1, e2);
   
        
// Compute gradient, which tells us how steep of an angle
        // we are approaching the *front* side of the triangle
   
    float dot = n * rayDelta;
   
        
// Check for a ray that is parallel to the triangle or not pointing toward the front face 
        // of the triangle.
        //
        // Note that this also will reject degenerate triangles and rays as well. We code this in a 
        // very particular way so that NANs will bail here. (This does not behave the same as 
        // "dot >= 0.0f" when NANs are involved.)
   
    if (!(dot < 0.0f)) 
            
return kNoIntersection;
        
        
// Compute d value for the plane equation. We will use the plane equation with d on the right side:
        //
        // Ax + By + Cz = d
   
    float d = n * p0;
   
        
// Compute parametric point of intersection with the plane containing the triangle, checking at the 
        // earliest possible stages for trivial rejection.
   
    float t = d – n * rayOrg;
   
        
// Is ray origin on the backside of the polygon? Again, we phrase the check so that NANs will bail.
   
    if (!(t <= 0.0f)) 
            
return kNoIntersection;
        
        
// Closer intersection already found? (Or does ray not reach the plane?)
        //
        // since dot < 0:
        //
        // t/dot > minT
        //
        // is the same as
        //
        // t < dot * minT
        //
        // (And then we invert it for NAN checking)
   
    if (!(t >= dot * minT)) 
            
return kNoIntersection;
        
        
// OK, ray intersects the plane. Compute actual parametric point of intersection.
   
    t /= dot;
   
        assert(t >= 0.0f);
        assert(t <= minT);
   
        
// Compute 3D point of intersection
   
    Vector3 p = rayOrg + rayDelta * t;
   
        
// Find dominant axis to select which plane
        // to project onto, and compute u's and v's
   
    float u0, u1, u2;
        
float v0, v1, v2;
   
        
if (fabs(n.x) > fabs(n.y)) 
        {
            
if (fabs(n.x) > fabs(n.z)) 
            {
                u0 = p.y – p0.y;
                u1 = p1.y – p0.y;
                u2 = p2.y – p0.y;
                v0 = p.z – p0.z;
                v1 = p1.z – p0.z;
                v2 = p2.z – p0.z;
            } 
            
else 
            {
                u0 = p.x – p0.x;
                u1 = p1.x – p0.x;
                u2 = p2.x – p0.x;
                v0 = p.y – p0.y;
                v1 = p1.y – p0.y;
                v2 = p2.y – p0.y;
            }
        } 
        
else 
        {
            
if (fabs(n.y) > fabs(n.z)) 
            {
                u0 = p.x – p0.x;
                u1 = p1.x – p0.x;
                u2 = p2.x – p0.x;
                v0 = p.z – p0.z;
                v1 = p1.z – p0.z;
                v2 = p2.z – p0.z;
            } 
            
else 
            {
                u0 = p.x – p0.x;
                u1 = p1.x – p0.x;
                u2 = p2.x – p0.x;
                v0 = p.y – p0.y;
                v1 = p1.y – p0.y;
                v2 = p2.y – p0.y;
            }
        }
   
        
// Compute denominator, check for invalid.
   
    float temp = u1 * v2 – v1 * u2;
   
        
if (!(temp != 0.0f)) 
            
return kNoIntersection;
        
        temp = 1.0f / temp;
   
        
// Compute barycentric coords, checking for out-of-range at each step
   
    float alpha = (u0 * v2 – v0 * u2) * temp;
   
        
if (!(alpha >= 0.0f)) 
            
return kNoIntersection;
        
        
float beta = (u1 * v0 – v1 * u0) * temp;
   
        
if (!(beta >= 0.0f)) 
            
return kNoIntersection;
        
        
float gamma = 1.0f - alpha - beta;
   
        
if (!(gamma >= 0.0f)) 
            
return kNoIntersection;
        
        
// Return parametric point of intersection
   
    return t;
    }

還有一個能優化昂貴計算的策略沒體現在上述代碼中:即預先計算結果。如果像多邊形向量這樣的值預先被計算出來的話,就可以采用更加優化的策略。

 

射線和AABB的相交性檢測

檢測AABB和射線的相交性非常重要,因為根據檢測的結果可以避免對更復雜物體的測試。(例如,我們要檢測射線與多個由三角網格組成的物體的相交性,可以先計算射線和三角網格的AABB的相交性。有時候可以一次就排除整個物體,而不必去檢測這個物體的所有三角形。)

Woo提出一種方法,先判斷矩形邊界框的哪個面會相交,再檢測射線與包含這個面的平面的相交性。如果交點在盒子中,那么射線與矩形邊界框相交,否則不存在相交。

cAABB3中rayIntersect()就是用Woo的技術來實現的。

    //---------------------------------------------------------------------------
    // Parametric intersection with a ray.  Returns parametric point
    // of intsersection in range 01 or a really big number (>1) if no
    // intersection.
    //
    // From "Fast Ray-Box Intersection," by Woo in Graphics Gems I, page 395.
    //
    // See 12.9.11
    //---------------------------------------------------------------------------
   
float AABB3::rayIntersect(const Vector3& rayOrg,        // origin of the ray
   
                          const Vector3& rayDelta,        // length and direction of the ray
   
                              Vector3* returnNormal) const    // optionally, the normal is returned
   
{
        
// We'll return this huge number if no intersection
   
    const float kNoIntersection = 1e30f;
   
        
// Check for point inside box, trivial reject, and determine parametric distance to each front face.
   
    bool inside = true;
   
        
float xt, xn;
   
        
if (rayOrg.x < min.x) 
        {
            xt = min.x - rayOrg.x;
            
if (xt > rayDelta.x) 
                
return kNoIntersection;
   
            xt /= rayDelta.x;
            inside = 
false;
            xn = -1.0f;
        } 
        
else if (rayOrg.x > max.x) 
        {
            xt = max.x - rayOrg.x;
            
if (xt < rayDelta.x) 
                
return kNoIntersection;
   
            xt /= rayDelta.x;
            inside = 
false;
            xn = 1.0f;
        } 
        
else
            xt = -1.0f;    
   
        
float yt, yn;
   
        
if (rayOrg.y < min.y) 
        {
            yt = min.y - rayOrg.y;
            
if (yt > rayDelta.y) 
                
return kNoIntersection;
   
            yt /= rayDelta.y;
            inside = 
false;
            yn = -1.0f;
        } 
        
else if (rayOrg.y > max.y) 
        {
            yt = max.y - rayOrg.y;
            
if (yt < rayDelta.y) 
                
return kNoIntersection;
   
            yt /= rayDelta.y;
            inside = 
false;
            yn = 1.0f;
        } 
        
else 
            yt = -1.0f;    
   
        
float zt, zn;
   
        
if (rayOrg.z < min.z) 
        {
            zt = min.z - rayOrg.z;
            
if (zt > rayDelta.z) 
                
return kNoIntersection;
   
            zt /= rayDelta.z;
            inside = 
false;
            zn = -1.0f;
        } 
        
else if (rayOrg.z > max.z) 
        {
            zt = max.z - rayOrg.z;
            
if (zt < rayDelta.z) 
                
return kNoIntersection;
   
            zt /= rayDelta.z;
            inside = 
false;
            zn = 1.0f;
        } 
        
else 
            zt = -1.0f;    
   
        
// Inside box?
   

        
if (inside) 
        {
            
if (returnNormal != NULL) 
            {
                *returnNormal = -rayDelta;
                returnNormal->normalize();
            }
   
            
return 0.0f;
        }
   
        
// Select farthest plane - this is
        // the plane of intersection.
   

        
int which = 0;
        
float t = xt;
   
        
if (yt > t) 
        {
            which = 1;
            t = yt;
        }
   
        
if (zt > t) 
        {
            which = 2;
            t = zt;
        }
   
        
switch (which) 
        {
        
case 0: // intersect with yz plane
   
      {
            
float y = rayOrg.y + rayDelta.y * t;
   
            
if (y < min.y || y > max.y) 
                
return kNoIntersection;
   
            
float z = rayOrg.z + rayDelta.z * t;
            
if (z < min.z || z > max.z) 
                
return kNoIntersection;
   
            
if (returnNormal != NULL) 
            {
                returnNormal->x = xn;
                returnNormal->y = 0.0f;
                returnNormal->z = 0.0f;
            }
          } 
          
break;
   
        
case 1: // intersect with xz plane
   
      {
            
float x = rayOrg.x + rayDelta.x * t;
            
if (x < min.x || x > max.x) 
                
return kNoIntersection;
   
            
float z = rayOrg.z + rayDelta.z * t;
            
if (z < min.z || z > max.z) 
                
return kNoIntersection;
   
            
if (returnNormal != NULL) 
            {
                returnNormal->x = 0.0f;
                returnNormal->y = yn;
                returnNormal->z = 0.0f;
            }
   
          } 
          
break;
   
        
case 2: // intersect with xy plane
   
      {
            
float x = rayOrg.x + rayDelta.x * t;
            
if (x < min.x || x > max.x) 
                
return kNoIntersection;
   
            
float y = rayOrg.y + rayDelta.y * t;
            
if (y < min.y || y > max.y) 
                
return kNoIntersection;
   
            
if (returnNormal != NULL) 
            {
                returnNormal->x = 0.0f;                                
                returnNormal->y = 0.0f;
                returnNormal->z = zn;
            }
          } 
          
break;
        }
   
        
// Return parametric point of intersection
   
    return t;
    }

posted on 2008-02-27 14:23 lovedday 閱讀(1234) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


公告

導航

統計

常用鏈接

隨筆分類(178)

3D游戲編程相關鏈接

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲国产一区二区精品专区| 亚洲图片自拍偷拍| 一区二区日本视频| 日韩亚洲欧美成人| 亚洲午夜一区| 欧美一区亚洲二区| 免费黄网站欧美| 亚洲国产天堂久久综合网| 欧美xxx成人| 亚洲巨乳在线| 欧美一进一出视频| 蜜臀av性久久久久蜜臀aⅴ四虎| 欧美成人高清视频| 国产精品国产馆在线真实露脸 | 黄色一区二区三区| 91久久综合亚洲鲁鲁五月天| 一区二区三区精品视频| 久久成人18免费观看| 欧美黑人多人双交| 在线视频精品| 欧美ed2k| 国产三区精品| 一区二区av在线| 久久久夜精品| 日韩午夜在线观看视频| 久久精品视频99| 国产精品国产| 亚洲日本在线视频观看| 欧美一级免费视频| 亚洲人成欧美中文字幕| 欧美一区二区三区视频免费| 欧美激情精品久久久久久变态| 国产精品久久久久久久久久ktv| 国产亚洲精品aa午夜观看| 99日韩精品| 久久人人爽人人| 亚洲一区二区三区激情| 欧美激情第六页| 在线观看不卡| 午夜亚洲伦理| 一本色道久久综合亚洲精品不卡| 欧美专区18| 国产精品一区二区久久国产| 99国产精品视频免费观看| 久久一本综合频道| 亚洲女性裸体视频| 国产精品第2页| 99视频精品| 91久久精品www人人做人人爽| 久久精品视频免费观看| 国产精品入口福利| 亚洲综合精品自拍| 亚洲精品久久久久| 欧美插天视频在线播放| 欧美视频在线观看一区二区| 你懂的国产精品永久在线| 亚洲影院一区| 欧美性猛交xxxx免费看久久久 | 亚洲国产天堂久久综合| 久久久亚洲人| 久久动漫亚洲| 又紧又大又爽精品一区二区| 久久尤物视频| 久久只有精品| 国户精品久久久久久久久久久不卡| 亚洲午夜精品网| 亚洲视频一二三| 国产精品一二三四| 久久久久久久97| 久久影视精品| 日韩亚洲综合在线| 一区二区三区免费观看| 国产精品免费看片| 欧美在线视频导航| 久久成人免费日本黄色| 亚洲国产日韩欧美在线图片 | 午夜精品一区二区三区在线| 亚洲欧美日韩国产另类专区| 国产亚洲欧美激情| 免费看的黄色欧美网站| 欧美影院在线播放| 在线观看一区二区精品视频| 亚洲国产日韩欧美综合久久| 欧美日韩不卡视频| 午夜一级久久| 久久久亚洲高清| 野花国产精品入口| 亚洲在线观看视频| 亚洲福利视频在线| 亚洲三级免费| 国产亚洲精品久| 亚洲高清自拍| 国产精品亚洲综合久久| 噜噜噜噜噜久久久久久91| 欧美激情91| 欧美一级视频精品观看| 麻豆精品视频| 欧美一级理论性理论a| 欧美成人精品不卡视频在线观看| 亚洲一区在线播放| 欧美99在线视频观看| 欧美永久精品| 欧美日韩在线播放| 欧美成人一区二区三区| 国产精品v欧美精品v日韩精品| 免费成人激情视频| 国产精品日本欧美一区二区三区| 欧美gay视频激情| 国产精品进线69影院| 欧美激情导航| 国产一区二区三区久久久| 一本色道久久精品| 亚洲精品系列| 久久免费高清视频| 久久精品亚洲精品| 欧美日本一区二区高清播放视频| 久久av一区二区三区漫画| 欧美国产日韩a欧美在线观看| 欧美一区久久| 欧美性大战久久久久| 欧美激情一区在线观看| 国内揄拍国内精品久久| 亚洲一区二区三区中文字幕| 亚洲免费成人av| 欧美不卡福利| 欧美黄色免费网站| 永久免费精品影视网站| 久久av一区二区三区| 久久精品道一区二区三区| 国产精品婷婷午夜在线观看| 亚洲乱码国产乱码精品精98午夜| 在线免费观看一区二区三区| 久久成人18免费观看| 欧美主播一区二区三区美女 久久精品人| 欧美日韩成人在线视频| 最新国产乱人伦偷精品免费网站| 亚洲福利国产精品| 男女精品视频| 欧美激情bt| 夜夜嗨av一区二区三区| 欧美日韩午夜剧场| 亚洲美女区一区| 亚洲午夜久久久| 国产精品麻豆成人av电影艾秋| 亚洲午夜av在线| 欧美一区二区高清在线观看| 国产欧美视频一区二区三区| 香蕉亚洲视频| 美腿丝袜亚洲色图| 亚洲精品免费一二三区| 欧美区国产区| 亚洲综合日韩| 麻豆精品在线播放| 亚洲伦伦在线| 欧美日韩在线播放三区| 亚洲一区尤物| 免费欧美在线| 亚洲每日在线| 国产欧美精品va在线观看| 久久激情五月丁香伊人| 欧美激情精品久久久| 在线视频一区观看| 国产女人精品视频| 久久影院亚洲| 亚洲天堂久久| 久久久久久久999| 亚洲精品九九| 国产精品丝袜白浆摸在线| 久久精品视频在线播放| 亚洲人成久久| 久久全球大尺度高清视频| 99精品国产在热久久下载| 国产精品午夜电影| 美腿丝袜亚洲色图| 亚洲一区免费看| 欧美激情一区二区三区在线视频| 午夜国产不卡在线观看视频| 亚洲高清视频在线观看| 欧美午夜一区二区三区免费大片 | 欧美.www| 亚洲欧美日韩精品一区二区| 欧美激情亚洲激情| 久久精品国产亚洲精品| 亚洲国产精品成人| 欧美日韩一区免费| 一区二区三区视频在线看| 久久亚洲欧美国产精品乐播| 99在线精品免费视频九九视| 国产一区二区黄| 欧美日韩专区| 欧美国产日韩亚洲一区| 久久精品视频免费| 午夜精品影院| 在线午夜精品自拍| 亚洲人成人99网站| 欧美成人精品三级在线观看| 欧美在线观看网站| 亚洲欧美日韩中文视频| 国产精品国产三级国产普通话蜜臀| 麻豆精品91|