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

# LineDistance.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/LineDistance.h"
    00027
    00028 namespace Lamp{
    00029
    00030 //------------------------------------------------------------------------------
    00031 // 点
    00032 //------------------------------------------------------------------------------
    00033 // 点距離の二乗
    00034 float LineDistance::squaredDistance(const Line& line, const Vector3& point){
    00035     const Vector3& direction = line.getDirection();
    00036     Vector3 distance = point - line.getOrigin();
    00037     float t = distance.dotProduct(direction);
    00038     t /= direction.getSquaredLength();
    00039     distance -= t * direction;
    00040     return distance.getSquaredLength();
    00041 }
    00042 //------------------------------------------------------------------------------
    00043 // ライン
    00044 //------------------------------------------------------------------------------
    00045 // ライン距離の二乗
    00046 float LineDistance::squaredDistance(const Line& line0, const Line& line1){
    00047     const Vector3& origin0 = line0.getOrigin();
    00048     const Vector3& direction0 = line0.getDirection();
    00049     const Vector3& origin1 = line1.getOrigin();
    00050     const Vector3& direction1 = line1.getDirection();
    00051     Vector3 direction2 = origin0 - origin1;
    00052     float dot00 = direction0.dotProduct(direction0);
    00053     float dot01 = direction0.dotProduct(direction1);
    00054     float dot11 = direction1.dotProduct(direction1);
    00055     float dot02 = direction0.dotProduct(direction2);
    00056     float dot12 = direction1.dotProduct(direction2);
    00057     float determ = dot00 * dot11 - dot01 * dot01;
    00058     float sValue, tValue, sDenom, tDenom;
    00059     sDenom = tDenom = determ;
    00060
    00061     // ラインが平行かチェック
    00062     if(determ <= Math::epsilon){
    00063         sValue = 0.f;
    00064         sDenom = 1.f;
    00065         tValue = dot12;
    00066         tDenom = dot11;
    00067     }else{
    00068         sValue = dot01 * dot12 - dot11 * dot02;
    00069         tValue = dot00 * dot12 - dot01 * dot02;
    00070     }
    00071
    00072     float s, t;
    00073     if(Math::abs(sDenom) > Math::epsilon){ s = sValue / sDenom; }
    00074     else{ s = 0.f; }
    00075     if(Math::abs(tDenom) > Math::epsilon){ t = tValue / tDenom; }
    00076     else{ t = 0.f; }
    00077
    00078     Vector3 direction =
    00079         (origin0 + (s * direction0)) - (origin1 + (t * direction1));
    00080     return direction.getSquaredLength();
    00081 }
    00082 //------------------------------------------------------------------------------
    00083 // 指向性ボックス
    00084 //------------------------------------------------------------------------------
    00085 // 指向性ボックス距離の二乗
    00086 float LineDistance::squaredDistance(const Line& line, const OrientedBox& ob){
    00087     Assert(false);
    00088     return 0.f;
    00089 }
    00090 //------------------------------------------------------------------------------
    00091 // 平面
    00092 //------------------------------------------------------------------------------
    00093 // 平面距離
    00094 float LineDistance::distance(const Line& line, const Plane& plane){
    00095     Assert(false);
    00096     return 0.f;
    00097 }
    00098 //------------------------------------------------------------------------------
    00099 // レイ
    00100 //------------------------------------------------------------------------------
    00101 // レイ距離の二乗
    00102 float LineDistance::squaredDistance(const Line& line, const Ray& ray){
    00103     const Vector3& origin0 = line.getOrigin();
    00104     const Vector3& direction0 = line.getDirection();
    00105     const Vector3& origin1 = ray.getOrigin();
    00106     const Vector3& direction1 = ray.getDirection();
    00107     Vector3 direction2 = origin0 - origin1;
    00108     float dot00 = direction0.dotProduct(direction0);
    00109     float dot01 = direction0.dotProduct(direction1);
    00110     float dot11 = direction1.dotProduct(direction1);
    00111     float dot02 = direction0.dotProduct(direction2);
    00112     float dot12 = direction1.dotProduct(direction2);
    00113     float determ = dot00 * dot11 - dot01 * dot01;
    00114     float sValue, tValue, sDenom, tDenom;
    00115     sDenom = tDenom = determ;
    00116
    00117     // レイが平行かチェック
    00118     if(determ <= Math::epsilon){
    00119         sValue = 0.f;
    00120         sDenom = 1.f;
    00121         tValue = dot12;
    00122         tDenom = dot11;
    00123     }else{
    00124         sValue = dot01 * dot12 - dot11 * dot02;
    00125         tValue = dot00 * dot12 - dot01 * dot02;
    00126     }
    00127
    00128     // t補正
    00129     if(tValue < 0.f){
    00130         tValue = 0.f;
    00131         sValue = -dot02;
    00132         sDenom = dot00;
    00133     }
    00134
    00135     float s, t;
    00136     if(Math::abs(sDenom) > Math::epsilon){ s = sValue / sDenom; }
    00137     else{ s = 0.f; }
    00138     if(Math::abs(tDenom) > Math::epsilon){ t = tValue / tDenom; }
    00139     else{ t = 0.f; }
    00140
    00141     Vector3 direction =
    00142         (origin0 + (s * direction0)) - (origin1 + (t * direction1));
    00143     return direction.getSquaredLength();
    00144 }
    00145 //------------------------------------------------------------------------------
    00146 // セグメント
    00147 //------------------------------------------------------------------------------
    00148 // セグメント距離の二乗
    00149 float LineDistance::squaredDistance(const Line& line, const Segment& segment){
    00150     const Vector3& origin0 = line.getOrigin();
    00151     const Vector3& direction0 = line.getDirection();
    00152     const Vector3& origin1 = segment.getOrigin();
    00153     const Vector3& direction1 = segment.getDirection();
    00154     Vector3 direction2 = origin0 - origin1;
    00155     float dot00 = direction0.dotProduct(direction0);
    00156     float dot01 = direction0.dotProduct(direction1);
    00157     float dot11 = direction1.dotProduct(direction1);
    00158     float dot02 = direction0.dotProduct(direction2);
    00159     float dot12 = direction1.dotProduct(direction2);
    00160     float determ = dot00 * dot11 - dot01 * dot01;
    00161     float sValue, tValue, sDenom, tDenom;
    00162     sDenom = tDenom = determ;
    00163
    00164     // セグメントが平行かチェック
    00165     if(determ <= Math::epsilon){
    00166         sValue = 0.f;
    00167         sDenom = 1.f;
    00168         tValue = dot12;
    00169         tDenom = dot11;
    00170     }else{
    00171         sValue = dot01 * dot12 - dot11 * dot02;
    00172         tValue = dot00 * dot12 - dot01 * dot02;
    00173     }
    00174
    00175     // t補正
    00176     if(tValue < 0.f){
    00177         tValue = 0.f;
    00178         sValue = -dot02;
    00179         sDenom = dot00;
    00180     }else if(tValue > tDenom){
    00181         tValue = tDenom;
    00182         sValue = dot01 - dot02;
    00183         sDenom = dot00;
    00184     }
    00185
    00186     float s, t;
    00187     if(Math::abs(sDenom) > Math::epsilon){ s = sValue / sDenom; }
    00188     else{ s = 0.f; }
    00189     if(Math::abs(tDenom) > Math::epsilon){ t = tValue / tDenom; }
    00190     else{ t = 0.f; }
    00191
    00192     Vector3 direction =
    00193         (origin0 + (s * direction0)) - (origin1 + (t * direction1));
    00194     return direction.getSquaredLength();
    00195 }
    00196 //------------------------------------------------------------------------------
    00197 // 球
    00198 //------------------------------------------------------------------------------
    00199 // 球距離の二乗
    00200 float LineDistance::squaredDistance(const Line& line, const Sphere& sphere){
    00201     Assert(false);
    00202     return 0.f;
    00203 }
    00204 //------------------------------------------------------------------------------
    00205 // 三角
    00206 //------------------------------------------------------------------------------
    00207 // 三角距離の二乗
    00208 float LineDistance::squaredDistance(const Line& line, const Triangle& triangle){
    00209     Assert(false);
    00210     return 0.f;
    00211 }
    00212 //------------------------------------------------------------------------------
    00213 } // End of namespace Lamp
    00214 //------------------------------------------------------------------------------