//============================================================================= // // OpenFlipper // Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen // www.openflipper.org // //----------------------------------------------------------------------------- // // License // // OpenFlipper is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // OpenFlipper is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with OpenFlipper. If not, see . // //----------------------------------------------------------------------------- // // $Revision$ // $Author$ // $Date$ // //============================================================================= //============================================================================= // // CLASS PlaneT // //============================================================================= #ifndef ACG_PLANE_HH #define ACG_PLANE_HH //== INCLUDES ================================================================= #include "../../Math/VectorT.hh" #include "../../Math/Matrix4x4T.hh" //== NAMESPACES =============================================================== namespace ACG { namespace Geometry { //== CLASS DEFINITION ========================================================= /** \class PlaneT PlaneT.hh This class stores a plane in normal form and provides useful algorithms for left/right test, itersection, and so on. **/ template class PlaneT { public: /// typedefs typedef VectorT Vec3; typedef VectorT Vec4; typedef Matrix4x4T Mat4x4; /// constructor: coefficients PlaneT( Scalar _a=0, Scalar _b=0, Scalar _c=0, Scalar _d=0 ) : coeffs_(_a, _b, _c, _d) { HNF(); } /// constructor: origin and normal PlaneT( const Vec3& _o, const Vec3& _n ) : coeffs_(_n[0], _n[1], _n[2], -(_n|_o)) { HNF(); } /// constructor: 3 points PlaneT( const Vec3& _v0, const Vec3& _v1, const Vec3& _v2 ) { Vec3 n = (_v1-_v0) % (_v2-_v0); coeffs_ = Vec4(n[0], n[1], n[2], -(n|_v0)); HNF(); } /// normal vector Vec3 normal() const { return Vec3(coeffs_[0], coeffs_[1], coeffs_[2]); } /// coeffitients const Vec4& coeffs() const { return coeffs_; } /// signed distance point-plane Scalar distance( const Vec3& _v ) const { return ( _v[0]*coeffs_[0] + _v[1]*coeffs_[1] + _v[2]*coeffs_[2] + coeffs_[3] ); } /// predicate: above plane bool operator() ( const Vec3& _v ) const { return distance(_v) > 0; } // INTERSECTION enum IntersectionTarget { Line, LineSegment, Ray }; // intersect with (infinite) line bool intersect_line( const Vec3& _v0, const Vec3& _v1, Vec3& _v, Scalar& _t ) const { return intersect(_v0, _v1, _v, _t, Line); } // intersect with ray bool intersect_ray( const Vec3& _v0, const Vec3& _v1, Vec3& _v, Scalar& _t ) const { return intersect(_v0, _v1, _v, _t, Ray); } // intersect with line segment bool intersect_linesegment( const Vec3& _v0, const Vec3& _v1, Vec3& _v, Scalar& _t ) const { return intersect(_v0, _v1, _v, _t, LineSegment); } /// general intersection bool intersect( const Vec3& _v0, const Vec3& _v1, Vec3& _v, Scalar& _t, IntersectionTarget _target ) const { #define SGN(d) ((d>0.0) ? 1 : -1) Scalar d0(distance(_v0)), d1(distance(_v1)); Scalar a0(fabs(d0)), a1(fabs(d1)); // endpoint on plane if (a0 < FLT_MIN) { _v = _v0; _t = 0.0; return true; } if (a1 < FLT_MIN) { _v = _v1; _t = 1.0; return true; } // triv accept if (SGN(d0) != SGN(d1)) { _t = (a0/(a0+a1)); _v = _v0*(1.0-_t) + _v1*_t; return true; } // depends on target else { if (_target == LineSegment) return false; if (fabs(d0-d1) < FLT_MIN) return false; // line parallel to plane else _t = d0/(d0-d1); if (_target == Ray && _t < 0.0) return false; _v = _v0*(1.0-_t) + _v1*_t; return true; } #undef SGN } /// affine transformation of the plane bool affine_transformation( const Mat4x4& _M ) { Mat4x4 M(_M); if (!M.invert()) return false; M.transpone(); affineTransformation_precomp(M); return true; } /// affine transformation of the plane (M^{-T} precomputed) void affine_transformation_precomp( const Mat4x4& _M_inverseTransposed ) { coeffs_ = _M_inverseTransposed*coeffs_; HNF(); } private: void HNF() { Scalar n = normal().norm(); if (n != 0.0) coeffs_ /= n; } Vec4 coeffs_; }; typedef PlaneT Planef; typedef PlaneT Planed; //============================================================================= } // namespace Geometry } // namespace ACG //============================================================================= #endif // ACG_PLANE_HH defined //=============================================================================