1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
//-----------------------------------------------------------------------------
// BSPLIB HEADER: Plane.h
//
// Copyright (c) 1997-1998 by Markus Hadwiger
// All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef _PLANE_H_
#define _PLANE_H_
// bsplib header files
#include "BspLibDefs.h"
#include "Vertex.h"
BSPLIB_NAMESPACE_BEGIN
// plane in 3-space; represented by normal and distance to origin -------------
//
class Plane {
enum {
NORMAL_VALID = 0x0001,
OFFSET_VALID = 0x0002,
PLANE_VALID = NORMAL_VALID | OFFSET_VALID,
};
public:
Plane() : m_valid( 0 ) { }
Plane( const Vector3& pnormal );
Plane( const Vector3& pnormal, double poffset );
Plane( const Vertex3& v1, const Vertex3& v2, const Vertex3& v3 );
~Plane() { }
int InitPlane( const Vertex3& v1, const Vertex3& v2, const Vertex3& v3 );
int CalcPlaneOffset( const Vertex3& vtx );
Vector3 getPlaneNormal() const { return m_normal; }
void setPlaneNormal( const Vector3& pnormal ) { m_normal = pnormal; }
double getPlaneOffset() const { return m_offset; }
void setPlaneOffset( double poffset ) { m_offset = poffset; }
int NormalValid() const { return ( ( m_valid & NORMAL_VALID ) == NORMAL_VALID ); }
int PlaneValid() const { return ( ( m_valid & PLANE_VALID ) == PLANE_VALID ); }
void ApplyScaleFactor( double sfac );
void EliminateDirectionality();
int PointContained( const Vertex3& point ) const;
int PointInPositiveHalfspace( const Vertex3& point ) const;
int PointInNegativeHalfspace( const Vertex3& point ) const;
private:
Vector3 m_normal; // normal of plane
double m_offset; // distance of plane to origin
int m_valid; // flag if plane specification indeed valid
};
// construct a plane from plane normal only: leave offset invalid -------------
inline Plane::Plane( const Vector3& pnormal )
{
m_normal = pnormal;
m_offset = 0.0;
m_valid = NORMAL_VALID;
}
// construct a plane from plane normal and distance to origin -----------------
inline Plane::Plane( const Vector3& pnormal, double poffset )
{
m_normal = pnormal;
m_offset = poffset;
m_valid = PLANE_VALID;
}
// construct a plane from three vertices (affine combination) -----------------
inline Plane::Plane( const Vertex3& v1, const Vertex3& v2, const Vertex3& v3 )
{
// normal is calculated so that the three vertices comprise a
// triangle with the front face in clockwise order
m_normal.CrossProduct( v3 - v1, v2 - v1 );
// m_valid will be set to 0 if the three vertices are collinear
m_valid = m_normal.Normalize() ? PLANE_VALID : 0;
// compute offset via dot product
m_offset = m_normal.DotProduct( v1 );
}
// init plane from three points (after construction!) -------------------------
inline int Plane::InitPlane( const Vertex3& v1, const Vertex3& v2, const Vertex3& v3 )
{
*this = Plane( v1, v2, v3 );
return m_valid;
}
// calculate plane's distance to origin using already valid normal ------------
inline int Plane::CalcPlaneOffset( const Vertex3& vtx )
{
// compute offset via dot product
m_offset = m_normal.DotProduct( vtx );
return ( m_valid |= OFFSET_VALID );
}
// apply scale factor to plane's distance to origin ---------------------------
inline void Plane::ApplyScaleFactor( double sfac )
{
// this will be needed if an object containing
// explicit plane information is scaled.
m_offset *= sfac;
}
// eliminate frontfacing/backfacing property; force positive offset -----------
inline void Plane::EliminateDirectionality()
{
if ( m_offset < 0.0 ) {
m_normal *= -1.0;
m_offset = -m_offset;
}
}
// determine if a point is contained in the plane -----------------------------
inline int Plane::PointContained( const Vertex3& point ) const
{
return ( fabs( m_normal.DotProduct( point ) - m_offset ) < EPS_POINT_ON_PLANE );
}
// determine if a point is contained in the positive open halfspace -----------
inline int Plane::PointInPositiveHalfspace( const Vertex3& point ) const
{
return ( m_normal.DotProduct( point ) - m_offset >= EPS_POINT_ON_PLANE );
}
// determine if a point is contained in the negative open halfspace -----------
inline int Plane::PointInNegativeHalfspace( const Vertex3& point ) const
{
return ( m_normal.DotProduct( point ) - m_offset <= -EPS_POINT_ON_PLANE );
}
BSPLIB_NAMESPACE_END
#endif // _PLANE_H_
|