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

Plane.h

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 #ifndef PLANE_H_
00026 #define PLANE_H_
00027 
00028 #include <Core/Primitive/Vector3.h>
00029 #include <Core/Primitive/Matrix33.h>
00030 #include <Core/Primitive/Matrix34.h>
00031 #include <Core/Primitive/Matrix44.h>
00032 
00033 namespace Lamp{
00034 
00035 class AxisAlignedBox;
00036 class Capsule;
00037 class Cone;
00038 class Line;
00039 class OrientedBox;
00040 class Ray;
00041 class Segment;
00042 class Sphere;
00043 class Triangle;
00044 
00045 //------------------------------------------------------------------------------
00046 /**
00047  * 平面
00048  *
00049  * このクラスは継承しないで下さい。
00050  */
00051 class Plane{
00052 public:
00053     //--------------------------------------------------------------------------
00054     // 定数
00055     //--------------------------------------------------------------------------
00056     /// ゼロ平面
00057     static const Plane zero;
00058 
00059     /// X単位平面
00060     static const Plane unitX;
00061 
00062     /// Y単位平面
00063     static const Plane unitY;
00064 
00065     /// Z単位平面
00066     static const Plane unitZ;
00067 
00068     //--------------------------------------------------------------------------
00069     // コンストラクタ
00070     //--------------------------------------------------------------------------
00071     /**
00072      * コンストラクタ
00073      *
00074      * このコンストラクタは初期値の設定を行わないため値は不定です。
00075      */
00076     inline Plane(){}
00077 
00078     /**
00079      * コンストラクタ
00080      * @param normal 法線の初期値
00081      * @param constant 定数の初期値
00082      */
00083 
00084     inline Plane(const Vector3& normal, float constant) :
00085         normal_(normal), constant_(constant){
00086     }
00087 
00088     /**
00089      * コンストラクタ
00090      * @param normalX 法線Xの初期値
00091      * @param normalY 法線Yの初期値
00092      * @param normalZ 法線Zの初期値
00093      * @param constant 定数の初期値
00094      */
00095 
00096     inline Plane(float normalX, float normalY, float normalZ, float constant) :
00097         normal_(normalX, normalY, normalZ), constant_(constant){
00098     }
00099 
00100     /**
00101      * コンストラクタ
00102      * @param source 初期値配列
00103      */
00104     inline explicit Plane(const float* const source) :
00105         normal_(source[0], source[1], source[2]), constant_(source[3]){
00106     }
00107 
00108     /**
00109      * コンストラクタ
00110      * @param vertex0 平面上の頂点0
00111      * @param vertex1 平面上の頂点1
00112      * @param vertex2 平面上の頂点2
00113      */
00114     inline Plane(
00115         const Vector3& vertex0, const Vector3& vertex1, const Vector3& vertex2){
00116         normal_ = Math3D::calculateNormal(vertex0, vertex1, vertex2);
00117         constant_ = -(normal_.dotProduct(vertex0));
00118     }
00119 
00120     /**
00121      * コンストラクタ
00122      * @param normal 法線の初期値
00123      * @param vertex 平面上の頂点
00124      */
00125     inline Plane(const Vector3& normal, const Vector3& vertex) :
00126         normal_(normal){
00127         constant_ = -(normal_.dotProduct(vertex));
00128     }
00129 
00130     //--------------------------------------------------------------------------
00131     // 値の設定
00132     //--------------------------------------------------------------------------
00133     /**
00134      * 値の設定
00135      * @param normal 設定する法線
00136      * @param constant 設定する定数
00137      */
00138     inline void set(const Vector3& normal, float constant){
00139         normal_ = normal;
00140         constant_ = constant;
00141     }
00142 
00143     /**
00144      * 値の設定
00145      * @param normalX 設定する法線X
00146      * @param normalY 設定する法線Y
00147      * @param normalZ 設定する法線Z
00148      * @param constant 設定する定数
00149      */
00150     inline void set(
00151         float normalX, float normalY, float normalZ, float constant){
00152         normal_.set(normalX, normalY, normalZ);
00153         constant_ = constant;
00154     }
00155 
00156     /**
00157      * 値の設定
00158      * @param source 設定値配列
00159      */
00160     inline void set(const float* const source){
00161         normal_.set(source[0], source[1], source[2]);
00162         constant_ = source[3];
00163     }
00164 
00165     /**
00166      * 値の設定
00167      * @param vertex0 平面上の頂点0
00168      * @param vertex1 平面上の頂点1
00169      * @param vertex2 平面上の頂点2
00170      */
00171     inline void set(
00172         const Vector3& vertex0, const Vector3& vertex1, const Vector3& vertex2){
00173         normal_ = Math3D::calculateNormal(vertex0, vertex1, vertex2);
00174         constant_ = -(normal_.dotProduct(vertex0));
00175     }
00176 
00177     /**
00178      * 値の設定
00179      * @param normal 設定する法線
00180      * @param vertex 平面上の頂点
00181      */
00182     inline void set(const Vector3& normal, const Vector3& vertex){
00183         normal_ = normal;
00184         constant_ = -(normal_.dotProduct(vertex));
00185     }
00186 
00187     /**
00188      * 法線の設定
00189      * @param normalX 設定する法線X
00190      * @param normalY 設定する法線Y
00191      * @param normalZ 設定する法線Z
00192      */
00193     inline void setNormal(float normalX, float normalY, float normalZ){
00194         normal_.set(normalX, normalY, normalZ);
00195     }
00196 
00197     /**
00198      * 法線の設定
00199      * @param normal 設定する法線
00200      */
00201     inline void setNormal(const Vector3& normal){ normal_ = normal; }
00202 
00203     /**
00204      * 定数の設定
00205      * @param constant 設定する定数
00206      */
00207     inline void setConstant(float constant){ constant_ = constant; }
00208 
00209     /**
00210      * 長さの設定
00211      * @param length 設定する長さ
00212      */
00213     inline const Plane& setLength(float length){
00214         float nowLength = normal_.getLength();
00215         // 長さが0の場合における対処はアプリケーションによって違うのでAssert
00216         Assert(nowLength >= Math::epsilon);
00217         float inverseLength = (length / nowLength);
00218         normal_ *= inverseLength;
00219         constant_ *= inverseLength;
00220         return *this;
00221     }
00222 
00223     //--------------------------------------------------------------------------
00224     // 値の取得
00225     //--------------------------------------------------------------------------
00226     /**
00227      * 法線の取得
00228      * @return 法線
00229      */
00230     inline const Vector3& getNormal() const{ return normal_; }
00231 
00232     /**
00233      * 定数の取得
00234      * @return 定数
00235      */
00236     inline float getConstant() const{ return constant_; }
00237 
00238     /**
00239      * 長さの取得
00240      * @return 長さ
00241      */
00242     inline float getLength() const{
00243         return Math::sqrt(normal_.x * normal_.x +
00244             normal_.y * normal_.y + normal_.z * normal_.z);
00245     }
00246 
00247     /**
00248      * 長さの二乗を取得
00249      * @return 長さの二乗
00250      */
00251     inline float getSquaredLength() const{
00252         return (normal_.x * normal_.x +
00253             normal_.y * normal_.y + normal_.z * normal_.z);
00254     }
00255 
00256     //--------------------------------------------------------------------------
00257     // 平面演算
00258     //--------------------------------------------------------------------------
00259     /**
00260      * 正規化
00261      * @return 正規化された平面
00262      */
00263     inline const Plane& normalize(){ return setLength(1.f); }
00264 
00265     /**
00266      * 内積を行う
00267      * @return 内積した値
00268      */
00269     inline float dotProduct(const Vector3& vector) const{
00270         return normal_.dotProduct(vector) + constant_;
00271     }
00272 
00273     //--------------------------------------------------------------------------
00274     /**
00275      * ゼロ平面かどうか
00276      * @return ゼロ平面ならtrueを返す
00277      */
00278     inline bool isZero() const{
00279         return (getLength() <= Math::epsilon);
00280     }
00281 
00282     /**
00283      * 単位平面かどうか
00284      * @return 単位平面ならtrueを返す
00285      */
00286     inline bool isUnit() const{
00287         return (Math::abs(getLength() - 1.f) <= Math::epsilon);
00288     }
00289 
00290     //--------------------------------------------------------------------------
00291     // トランスフォーム
00292     //--------------------------------------------------------------------------
00293     /**
00294      * トランスフォーム
00295      * @param matrix 乗算する行列
00296      * @return 変換後の球
00297      */
00298     inline Plane transform(const Matrix33& matrix) const{
00299         Plane result;
00300         result.normal_ = matrix * normal_;
00301         result.constant_ = constant_;
00302         return result;
00303     }
00304 
00305     /**
00306      * トランスフォーム
00307      * @param matrix 乗算する行列
00308      * @return 変換後の球
00309      */
00310     inline Plane transform(const Matrix34& matrix) const{
00311         Plane result;
00312         result.normal_ = matrix.multiply33(normal_);
00313         Vector3 trans = matrix.getTranslation();
00314         trans.set(
00315             matrix.m00 * trans.x + matrix.m10 * trans.y + matrix.m20 * trans.z,
00316             matrix.m01 * trans.x + matrix.m11 * trans.y + matrix.m21 * trans.z,
00317             matrix.m02 * trans.x + matrix.m12 * trans.y + matrix.m22 * trans.z);
00318         result.constant_ = constant_ - trans.dotProduct(normal_);
00319         return result;
00320     }
00321 
00322     /**
00323      * トランスフォーム
00324      * @param matrix 乗算する行列
00325      * @return 変換後の球
00326      */
00327     inline Plane transform(const Matrix44& matrix) const{
00328         Plane result;
00329         result.normal_ = matrix.multiply33(normal_);
00330         Vector3 trans = matrix.getTranslation();
00331         trans.set(
00332             matrix.m00 * trans.x + matrix.m10 * trans.y + matrix.m20 * trans.z,
00333             matrix.m01 * trans.x + matrix.m11 * trans.y + matrix.m21 * trans.z,
00334             matrix.m02 * trans.x + matrix.m12 * trans.y + matrix.m22 * trans.z);
00335         result.constant_ = constant_ - trans.dotProduct(normal_);
00336         return result;
00337     }
00338 
00339     //--------------------------------------------------------------------------
00340     /**
00341      * スケール有りトランスフォーム
00342      * @param matrix 乗算する行列
00343      * @return 変換後の球
00344      */
00345     inline Plane scaledTransform(const Matrix33& matrix) const{
00346         Plane result;
00347         Matrix33 normalMatrix;
00348         matrix.invert(&normalMatrix);
00349         normalMatrix.transpose();
00350         result.normal_ = normalMatrix * normal_;
00351         result.constant_ = constant_;
00352         return result;
00353     }
00354 
00355     /**
00356      * スケール有りトランスフォーム
00357      * @param matrix 乗算する行列
00358      * @return 変換後の球
00359      */
00360     inline Plane scaledTransform(const Matrix34& matrix) const{
00361         Plane result;
00362         Matrix33 normalMatrix;
00363         normalMatrix.set(matrix);
00364         normalMatrix.invert();
00365         result.constant_ = constant_ -
00366             (normalMatrix * matrix.getTranslation()).dotProduct(normal_);
00367         normalMatrix.transpose();
00368         result.normal_ = normalMatrix * normal_;
00369         return result;
00370     }
00371 
00372     /**
00373      * スケール有りトランスフォーム
00374      * @param matrix 乗算する行列
00375      * @return 変換後の球
00376      */
00377     inline Plane scaledTransform(const Matrix44& matrix) const{
00378         Plane result;
00379         Matrix33 normalMatrix;
00380         normalMatrix.set(matrix);
00381         normalMatrix.invert();
00382         result.constant_ = constant_ -
00383             (normalMatrix * matrix.getTranslation()).dotProduct(normal_);
00384         normalMatrix.transpose();
00385         result.normal_ = normalMatrix * normal_;
00386         return result;
00387     }
00388 
00389     //--------------------------------------------------------------------------
00390     // 距離
00391     //--------------------------------------------------------------------------
00392     /**
00393      * 点距離
00394      * @param point 距離判定する点
00395      * @return 距離
00396      */
00397     float getDistance(const Vector3& point) const;
00398 
00399     /**
00400      * 点距離の二乗
00401      * @param point 距離判定する点
00402      * @return 距離の二乗
00403      */
00404     float getSquaredDistance(const Vector3& point) const{
00405         float distance = getDistance(point);
00406         return (distance * distance);
00407     }
00408 
00409     //--------------------------------------------------------------------------
00410     /**
00411      * 軸沿いボックス距離
00412      * @param axisAlignedBox 距離判定する軸沿いボックス
00413      * @return 距離
00414      */
00415     float getDistance(const AxisAlignedBox& axisAlignedBox) const;
00416 
00417     /**
00418      * 軸沿いボックス距離の二乗
00419      * @param axisAlignedBox 距離判定する軸沿いボックス
00420      * @return 距離の二乗
00421      */
00422     float getSquaredDistance(const AxisAlignedBox& axisAlignedBox) const{
00423         float distance = getDistance(axisAlignedBox);
00424         return (distance * distance);
00425     }
00426 
00427     //--------------------------------------------------------------------------
00428     /**
00429      * カプセル距離
00430      * @param capsule 距離判定するカプセル
00431      * @return 距離
00432      */
00433     float getDistance(const Capsule& capsule) const;
00434 
00435     /**
00436      * カプセル距離の二乗
00437      * @param capsule 距離判定するカプセル
00438      * @return 距離の二乗
00439      */
00440     float getSquaredDistance(const Capsule& capsule) const{
00441         float distance = getDistance(capsule);
00442         return (distance * distance);
00443     }
00444 
00445     //--------------------------------------------------------------------------
00446     /**
00447      * コーン距離
00448      * @param cone 距離判定するコーン
00449      * @return 距離
00450      */
00451     float getDistance(const Cone& cone) const;
00452 
00453     /**
00454      * コーン距離の二乗
00455      * @param cone 距離判定するコーン
00456      * @return 距離の二乗
00457      */
00458     float getSquaredDistance(const Cone& cone) const{
00459         float distance = getDistance(cone);
00460         return (distance * distance);
00461     }
00462 
00463     //--------------------------------------------------------------------------
00464     /**
00465      * ライン距離
00466      * @param line 距離判定するライン
00467      * @return 距離
00468      */
00469     float getDistance(const Line& line) const;
00470 
00471     /**
00472      * ライン距離の二乗
00473      * @param line 距離判定するライン
00474      * @return 距離の二乗
00475      */
00476     float getSquaredDistance(const Line& line) const{
00477         float distance = getDistance(line);
00478         return (distance * distance);
00479     }
00480 
00481     //--------------------------------------------------------------------------
00482     /**
00483      * 指向性ボックス距離
00484      * @param orientedBox 距離判定する指向性ボックス
00485      * @return 距離
00486      */
00487     float getDistance(const OrientedBox& orientedBox) const;
00488 
00489     /**
00490      * 指向性ボックス距離の二乗
00491      * @param orientedBox 距離判定する指向性ボックス
00492      * @return 距離の二乗
00493      */
00494     float getSquaredDistance(const OrientedBox& orientedBox) const{
00495         float distance = getDistance(orientedBox);
00496         return (distance * distance);
00497     }
00498 
00499     //--------------------------------------------------------------------------
00500     /**
00501      * 平面距離
00502      * @param plane 距離判定する平面
00503      * @return 距離
00504      */
00505     float getDistance(const Plane& plane) const;
00506 
00507     /**
00508      * 平面距離の二乗
00509      * @param plane 距離判定する平面
00510      * @return 距離の二乗
00511      */
00512     float getSquaredDistance(const Plane& plane) const{
00513         float distance = getDistance(plane);
00514         return (distance * distance);
00515     }
00516 
00517     //--------------------------------------------------------------------------
00518     /**
00519      * レイ距離
00520      * @param ray 距離判定するレイ
00521      * @return 距離
00522      */
00523     float getDistance(const Ray& ray) const;
00524 
00525     /**
00526      * レイ距離の二乗
00527      * @param ray 距離判定するレイ
00528      * @return 距離の二乗
00529      */
00530     float getSquaredDistance(const Ray& ray) const{
00531         float distance = getDistance(ray);
00532         return (distance * distance);
00533     }
00534 
00535     //--------------------------------------------------------------------------
00536     /**
00537      * セグメント距離
00538      * @param segment 距離判定するセグメント
00539      * @return 距離
00540      */
00541     float getDistance(const Segment& segment) const;
00542 
00543     /**
00544      * セグメント距離の二乗
00545      * @param segment 距離判定するセグメント
00546      * @return 距離の二乗
00547      */
00548     float getSquaredDistance(const Segment& segment) const{
00549         float distance = getDistance(segment);
00550         return (distance * distance);
00551     }
00552 
00553     //--------------------------------------------------------------------------
00554     /**
00555      * 球距離
00556      * @param sphere 距離判定する球
00557      * @return 距離
00558      */
00559     float getDistance(const Sphere& sphere) const;
00560 
00561     /**
00562      * 球距離の二乗
00563      * @param sphere 距離判定する球
00564      * @return 距離の二乗
00565      */
00566     float getSquaredDistance(const Sphere& sphere) const{
00567         float distance = getDistance(sphere);
00568         return (distance * distance);
00569     }
00570 
00571     //--------------------------------------------------------------------------
00572     /**
00573      * 三角距離
00574      * @param triangle 距離判定する三角
00575      * @return 距離
00576      */
00577     float getDistance(const Triangle& triangle) const;
00578 
00579     /**
00580      * 三角距離の二乗
00581      * @param triangle 距離判定する三角
00582      * @return 距離の二乗
00583      */
00584     float getSquaredDistance(const Triangle& triangle) const{
00585         float distance = getDistance(triangle);
00586         return (distance * distance);
00587     }
00588 
00589     //--------------------------------------------------------------------------
00590     // 交差
00591     //--------------------------------------------------------------------------
00592     /**
00593      * 点交差
00594      * @param point 交差判定する点
00595      * @param range 交差範囲
00596      * @return 交差していればtrue
00597      */
00598     bool intersect(const Vector3& point, float range = Math::epsilon) const;
00599 
00600     //--------------------------------------------------------------------------
00601     /**
00602      * 軸沿いボックス交差
00603      * @param axisAlignedBox 交差判定する軸沿いボックス
00604      * @return 交差していればtrue
00605      */
00606     bool intersect(const AxisAlignedBox& axisAlignedBox) const;
00607 
00608     //--------------------------------------------------------------------------
00609     /**
00610      * カプセル交差
00611      * @param capsule 交差判定するカプセル
00612      * @return 交差していればtrue
00613      */
00614     bool intersect(const Capsule& capsule) const;
00615 
00616     //--------------------------------------------------------------------------
00617     /**
00618      * コーン交差
00619      * @param cone 交差判定するコーン
00620      * @return 交差していればtrue
00621      */
00622     bool intersect(const Cone& cone) const;
00623 
00624     //--------------------------------------------------------------------------
00625     /**
00626      * ライン交差
00627      * @param line 交差判定するライン
00628      * @return 交差していればtrue
00629      */
00630     bool intersect(const Line& line) const;
00631 
00632     //--------------------------------------------------------------------------
00633     /**
00634      * 指向性ボックス交差
00635      * @param orientedBox 交差判定する指向性ボックス
00636      * @return 交差していればtrue
00637      */
00638     bool intersect(const OrientedBox& orientedBox) const;
00639 
00640     //--------------------------------------------------------------------------
00641     /**
00642      * 平面交差
00643      * @param plane 交差判定する平面
00644      * @return 交差していればtrue
00645      */
00646     bool intersect(const Plane& plane) const;
00647 
00648     //--------------------------------------------------------------------------
00649     /**
00650      * レイ交差
00651      * @param ray 交差判定するレイ
00652      * @return 交差していればtrue
00653      */
00654     bool intersect(const Ray& ray) const;
00655 
00656     //--------------------------------------------------------------------------
00657     /**
00658      * セグメント交差
00659      * @param segment 交差判定するセグメント
00660      * @return 交差していればtrue
00661      */
00662     bool intersect(const Segment& segment) const;
00663 
00664     //--------------------------------------------------------------------------
00665     /**
00666      * 球交差
00667      * @param sphere 交差判定する球
00668      * @return 交差していればtrue
00669      */
00670     bool intersect(const Sphere& sphere) const;
00671 
00672     //--------------------------------------------------------------------------
00673     /**
00674      * 三角交差
00675      * @param triangle 交差判定する三角
00676      * @return 交差していればtrue
00677      */
00678     bool intersect(const Triangle& triangle) const;
00679 
00680     //--------------------------------------------------------------------------
00681     // 論理演算
00682     //--------------------------------------------------------------------------
00683     /**
00684      * 平面が同じかどうか
00685      * @param target 比較する平面
00686      * @return 同じ値であればtrueを返す
00687      */
00688     inline bool operator ==(const Plane& target) const{
00689         return ((normal_ == target.normal_) && (constant_ == target.constant_));
00690     }
00691 
00692     /**
00693      * 平面が同じかどうか
00694      * @param target 比較する平面
00695      * @param epsilon 誤差
00696      * @return 誤差の範囲内で同じ値であればtrueを返す
00697      */
00698     inline bool epsilonEquals(
00699         const Plane& target, float epsilon) const{
00700         Assert(epsilon >= 0.f);
00701         return (normal_.epsilonEquals(target.normal_, epsilon) &&
00702             (Math::abs(constant_ - target.constant_) <= epsilon));
00703     }
00704 
00705     /**
00706      * 平面が同じでないかどうか
00707      * @param target 比較する平面
00708      * @return 同じでない値であればtrueを返す
00709      */
00710     inline bool operator !=(const Plane& target) const{
00711         return ((normal_ != target.normal_) || (constant_ != target.constant_));
00712     }
00713 
00714     /**
00715      * 平面が同じでないかどうか
00716      * @param target 比較する平面
00717      * @param epsilon 誤差
00718      * @return 誤差の範囲内で同じでない値であればtrueを返す
00719      */
00720     inline bool notEpsilonEquals(
00721         const Plane& target, float epsilon) const{
00722         Assert(epsilon >= 0.f);
00723         return (normal_.notEpsilonEquals(target.normal_, epsilon) ||
00724             (Math::abs(constant_ - target.constant_) > epsilon));
00725     }
00726 
00727     //--------------------------------------------------------------------------
00728     // その他
00729     //--------------------------------------------------------------------------
00730     /**
00731      * 文字列化
00732      * @return 平面の文字列表記
00733      */
00734     inline String toString() const{
00735         String returnString;
00736         returnString.format("{ ( %.8f, %.8f, %.8f ) %.8f }",
00737             normal_.x, normal_.y, normal_.z, constant_);
00738         return returnString;
00739     }
00740 
00741 private:
00742     //--------------------------------------------------------------------------
00743     // メンバ変数
00744     //--------------------------------------------------------------------------
00745     // 法線
00746     Vector3 normal_;
00747     // 定数
00748     float constant_;
00749 
00750 };
00751 
00752 //------------------------------------------------------------------------------
00753 } // End of namespace Lamp
00754 #endif // End of PLANE_H_
00755 //------------------------------------------------------------------------------

Generated on Wed Mar 16 10:29:33 2005 for Lamp by doxygen 1.3.2