Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

# RayDistance.cpp

Go to the documentation of this file.

    00001 //------------------------------------------------------------------------------
    00002 // Lamp : Open source game middleware
    00003 // Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
    00004 //
    00005 // This library is free software; you can redistribute it and/or
    00006 // modify it under the terms of the GNU Lesser General Public
    00007 // License as published by the Free Software Foundation; either
    00008 // version 2.1 of the License, or (at your option) any later version.
    00009 //
    00010 // This library is distributed in the hope that it will be useful,
    00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00013 // Lesser General Public License for more details.
    00014 //
    00015 // You should have received a copy of the GNU Lesser General Public
    00016 // License along with this library; if not, write to the Free Software
    00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00018 //------------------------------------------------------------------------------
    00019
    00020 /** @file
    00021  * レイ距離実装
    00022  * @author Junpee
    00023  */
    00024
    00025 #include "LampBasic.h"
    00026 #include "Geometry/Distance/RayDistance.h"
    00027
    00028 namespace Lamp{
    00029
    00030 //------------------------------------------------------------------------------
    00031 // 点
    00032 //------------------------------------------------------------------------------
    00033 // 点距離の二乗
    00034 float RayDistance::squaredDistance(const Ray& ray, const Vector3& point){
    00035     const Vector3& direction = ray.getDirection();
    00036     Vector3 distance = point - ray.getOrigin();
    00037     float t = distance.dotProduct(direction);
    00038     // tが-だったら投影しない
    00039     if(t > 0.f){
    00040         t /= direction.getSquaredLength();
    00041         distance -= t * direction;
    00042 //  }else{
    00043 //      t = 0.f;
    00044     }
    00045     return distance.getSquaredLength();
    00046 }
    00047 //------------------------------------------------------------------------------
    00048 // レイ
    00049 //------------------------------------------------------------------------------
    00050 // レイ距離の二乗
    00051 float RayDistance::squaredDistance(const Ray& ray0, const Ray& ray1){
    00052     const Vector3& origin0 = ray0.getOrigin();
    00053     const Vector3& direction0 = ray0.getDirection();
    00054     const Vector3& origin1 = ray1.getOrigin();
    00055     const Vector3& direction1 = ray1.getDirection();
    00056     Vector3 direction2 = origin0 - origin1;
    00057     float dot00 = direction0.dotProduct(direction0);
    00058     float dot01 = direction0.dotProduct(direction1);
    00059     float dot11 = direction1.dotProduct(direction1);
    00060     float dot02 = direction0.dotProduct(direction2);
    00061     float dot12 = direction1.dotProduct(direction2);
    00062     float determ = dot00 * dot11 - dot01 * dot01;
    00063     float sValue, tValue, sDenom, tDenom;
    00064     sDenom = tDenom = determ;
    00065
    00066     // レイが平行かチェック
    00067     if(determ <= Math::epsilon){
    00068         sValue = 0.f;
    00069         sDenom = 1.f;
    00070         tValue = dot12;
    00071         tDenom = dot11;
    00072     }else{
    00073         sValue = dot01 * dot12 - dot11 * dot02;
    00074         tValue = dot00 * dot12 - dot01 * dot02;
    00075     }
    00076
    00077     // s補正
    00078     if(sValue < 0.f){
    00079         sValue = 0.f;
    00080         tValue = dot12;
    00081         tDenom = dot11;
    00082     }
    00083
    00084     // t補正
    00085     if(tValue < 0.f){
    00086         tValue = 0.f;
    00087         if((-dot02) < 0.f){
    00088             sValue = 0.f;
    00089         }else{
    00090             sValue = -dot02;
    00091             sDenom = dot00;
    00092         }
    00093     }
    00094
    00095     float s, t;
    00096     if(Math::abs(sDenom) > Math::epsilon){ s = sValue / sDenom; }
    00097     else{ s = 0.f; }
    00098     if(Math::abs(tDenom) > Math::epsilon){ t = tValue / tDenom; }
    00099     else{ t = 0.f; }
    00100
    00101     Vector3 direction =
    00102         (origin0 + (s * direction0)) - (origin1 + (t * direction1));
    00103     return direction.getSquaredLength();
    00104 }
    00105 //------------------------------------------------------------------------------
    00106 // セグメント
    00107 //------------------------------------------------------------------------------
    00108 // セグメント距離の二乗
    00109 float RayDistance::squaredDistance(const Ray& ray, const Segment& segment){
    00110     const Vector3& origin0 = ray.getOrigin();
    00111     const Vector3& direction0 = ray.getDirection();
    00112     const Vector3& origin1 = segment.getOrigin();
    00113     const Vector3& direction1 = segment.getDirection();
    00114     Vector3 direction2 = origin0 - origin1;
    00115     float dot00 = direction0.dotProduct(direction0);
    00116     float dot01 = direction0.dotProduct(direction1);
    00117     float dot11 = direction1.dotProduct(direction1);
    00118     float dot02 = direction0.dotProduct(direction2);
    00119     float dot12 = direction1.dotProduct(direction2);
    00120     float determ = dot00 * dot11 - dot01 * dot01;
    00121     float sValue, tValue, sDenom, tDenom;
    00122     sDenom = tDenom = determ;
    00123
    00124     // セグメントが平行かチェック
    00125     if(determ <= Math::epsilon){
    00126         sValue = 0.f;
    00127         sDenom = 1.f;
    00128         tValue = dot12;
    00129         tDenom = dot11;
    00130     }else{
    00131         sValue = dot01 * dot12 - dot11 * dot02;
    00132         tValue = dot00 * dot12 - dot01 * dot02;
    00133     }
    00134
    00135     // s補正
    00136     if(sValue < 0.f){
    00137         sValue = 0.f;
    00138         tValue = dot12;
    00139         tDenom = dot11;
    00140     }
    00141
    00142     // t補正
    00143     if(tValue < 0.f){
    00144         tValue = 0.f;
    00145         float tmpS = (-dot02);
    00146         if(tmpS < 0.f){
    00147             sValue = 0.f;
    00148         }else{
    00149             sValue = tmpS;
    00150             sDenom = dot00;
    00151         }
    00152     }else if(tValue > tDenom){
    00153         tValue = tDenom;
    00154         float tmpS = dot01 - dot02;
    00155         if(tmpS < 0.f){
    00156             sValue = 0.f;
    00157         }else{
    00158             sValue = tmpS;
    00159             sDenom = dot00;
    00160         }
    00161     }
    00162
    00163     float s, t;
    00164     if(Math::abs(sDenom) > Math::epsilon){ s = sValue / sDenom; }
    00165     else{ s = 0.f; }
    00166     if(Math::abs(tDenom) > Math::epsilon){ t = tValue / tDenom; }
    00167     else{ t = 0.f; }
    00168
    00169     Vector3 direction =
    00170         (origin0 + (s * direction0)) - (origin1 + (t * direction1));
    00171     return direction.getSquaredLength();
    00172 }
    00173 //------------------------------------------------------------------------------
    00174 // 球
    00175 //------------------------------------------------------------------------------
    00176 // 球距離の二乗
    00177 float RayDistance::squaredDistance(const Ray& ray, const Sphere& sphere){
    00178     Assert(false);
    00179     return 0.f;
    00180 }
    00181 //------------------------------------------------------------------------------
    00182 // 三角
    00183 //------------------------------------------------------------------------------
    00184 // 三角距離の二乗
    00185 float RayDistance::squaredDistance(const Ray& ray, const Triangle& triangle){
    00186     Assert(false);
    00187     return 0.f;
    00188 }
    00189 //------------------------------------------------------------------------------
    00190 } // End of namespace Lamp
    00191 //------------------------------------------------------------------------------