/** * @author Edouard DUPIN * * @copyright 2011, Edouard DUPIN, all right reserved * * @license APACHE v2.0 (see license file) */ #include #ifndef __ETK_TYPES_PLANE_H__ #define __ETK_TYPES_PLANE_H__ #include #include namespace etk { template class Plane { public : //member variables etk::Vector3D m_normal; //!< X.N+intercept=0 T m_intercept; public: /***************************************************** * Constructor *****************************************************/ Plane() : m_normal(0, 0, 0), m_intercept(0) { } Plane(etk::Vector3D _normal, T _intercept=0) : m_normal(_normal), m_intercept(_intercept) { } Plane(const Plane& obj) : m_normal(obj.m_normal), m_intercept(obj.m_intercept) { } /***************************************************** * Destructor *****************************************************/ ~Plane() { }; /** * @brief * @param[in,out] * @return */ void setNormal(const etk::Vector3D& _obj) { m_normal = _obj; }; /** * @brief * @param[in,out] * @return */ void setIntercept(float _intercept) { m_intercept=_intercept; }; /** * @brief * @param[in,out] * @return */ void setFromPoints(const etk::Vector3D& p0, const etk::Vector3D& p1, const etk::Vector3D& p2) { m_normal = (_p1 - _p0).crossProduct(_p2 - _p0); m_normal.normalize(); calculateIntercept(_p0); }; /** * @brief * @param[in,out] * @return */ void calculateIntercept(const etk::Vector3D& _pointOnPlane) { m_intercept=-m_normal.dotProduct(_pointOnPlane); } /** * @brief * @param[in,out] * @return */ void normalize() { float normalLength=m_normal.getLength(); m_normal/=normalLength; m_intercept/=normalLength; }; /** * @brief * @param[in,out] * @return */ etk::Vector3D getNormal() { return m_normal; }; /** * @brief * @param[in,out] * @return */ float getIntercept() { return m_intercept; } //find point of intersection of 3 planes /** * @brief * @param[in,out] * @return */ bool intersect3(const Plane& _p2, const Plane& _p3, etk::Vector3D& _result) { float denominator = m_normal.dotProduct((_p2.m_normal).crossProduct(_p3.m_normal)); //scalar triple product of normals if(denominator==0.0f) { //no intersection return false; } etk::Vector3D temp1, temp2, temp3; temp1 = (_p2.m_normal.crossProduct(_p3.m_normal))*m_intercept; temp2 = (_p3.m_normal.crossProduct(m_normal)) * _p2.m_intercept; temp3 = (m_normal.crossProduct(_p2.m_normal)) * _p3.m_intercept; result=(temp1+temp2+temp3)/(-denominator); return true; }; /** * @brief * @param[in,out] * @return */ float getDistance(const etk::Vector3D& _point) const { return _point.x * m_normal.x + _point.y * m_normal.y + _point.z * m_normal.z + m_intercept; }; /** * @brief * @param[in,out] * @return */ Plane linearInterpolate(const Plane& _p2, float _factor) { Plane result; result.m_normal=m_normal*(1.0f-_factor) + _p2.m_normal*_factor; result.m_normal.normalize(); result.m_intercept=m_intercept*(1.0f-_factor) + _p2.m_intercept*_factor; return result; }; //operators /** * @brief * @param[in,out] * @return */ bool operator==(const Plane & _obj) const { if( m_normal == _obj.m_normal && m_intercept == _obj.m_intercept) { return true; } return false; }; /** * @brief * @param[in,out] * @return */ bool operator!=(const Plane& _obj) const { return!((*this) == _obj); } //unary operators /** * @brief * @param[in,out] * @return */ Plane operator-() const { return Plane(-m_normal, -m_intercept); } /** * @brief * @param[in,out] * @return */ Plane operator+() const { return *this; } }; }; #endif