// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_plane #define tools_plane #include "line" namespace tools { template class plane { protected: typedef typename VEC3::elem_t T; public: plane(){} plane(const VEC3& a_p0,const VEC3& a_p1,const VEC3& a_p2) { // Construct a plane given 3 points. // Orientation is computed by taking (p1 - p0) x (p2 - p0) and // pointing the normal in that direction. VEC3 P = a_p1; P.subtract(a_p0); VEC3 P2 = a_p2; P2.subtract(a_p0); P.cross(P2,m_normal); if(!m_normal.normalize()) {} //throw m_distance = m_normal.v0() * a_p0.v0() + m_normal.v1() * a_p0.v1() + m_normal.v2() * a_p0.v2(); } plane(const VEC3& a_normal,const T& a_distance){ set(a_normal,a_distance); } plane(const VEC3& a_normal,const VEC3& a_point){ set(a_normal,a_point); } virtual ~plane() {} public: plane(const plane& a_from) :m_normal(a_from.m_normal) ,m_distance(a_from.m_distance) {} plane& operator=(const plane& a_from) { m_normal = a_from.m_normal; m_distance = a_from.m_distance; return *this; } public: bool is_valid() const {return m_normal.length()?true:false;} void offset(const T& a_distance){ // Offset a plane by a given distance. m_distance += a_distance; } bool intersect(const line& a_line,VEC3& a_intersection) const { // Intersect line and plane, returning true if there is an intersection // false if line is parallel to plane const VEC3& pos = a_line.position(); const VEC3& dir = a_line.direction(); T d = m_normal.dot(dir); if(d==T()) return false; T t = (m_distance - m_normal.dot(pos))/d; //a_intersection = pos + t * dir; a_intersection = dir; a_intersection.multiply(t); a_intersection.add(pos); return true; } bool is_in_half_space(const VEC3& a_point) const { // Returns true if the given point is within the half-space // defined by the plane //vec pos = m_normal * m_distance; VEC3 pos = m_normal; pos.multiply(-m_distance); pos.add(a_point); return (m_normal.dot(pos) >= T() ? true : false); } const VEC3& normal() const {return m_normal;} T distance_from_origin() const {return m_distance;} T distance(const VEC3& a_point) const { // Return the distance from point to plane. Positive distance means // the point is in the plane's half space. return a_point.dot(m_normal) - m_distance; } void set(const VEC3& a_normal,const T& a_distance){ m_normal = a_normal; if(!m_normal.normalize()) {} //throw m_distance = a_distance; } void set(const VEC3& a_normal,const VEC3& a_point){ // Construct a plane given normal and a point to pass through // Orientation is given by the normal vector n. m_normal = a_normal; if(!m_normal.normalize()) {} //throw m_distance = m_normal.v0() * a_point.v0() + m_normal.v1() * a_point.v1() + m_normal.v2() * a_point.v2(); } public: //iv2sg const VEC3& getNormal() const {return m_normal;} protected: // equation of the plane is : // norm[0]*x+norm[1]*y+norm[2]*z = dist VEC3 m_normal; //normalized. T m_distance; }; } #endif