128 lines
3.2 KiB
Plaintext
128 lines
3.2 KiB
Plaintext
// 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 VEC3>
|
|
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<VEC3>& 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 = dir;
|
|
a_intersection.multiply(t);
|
|
a_intersection.add(pos);
|
|
//a_intersection = pos + t * dir;
|
|
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
|