13 #ifndef FELKELCOMPONENTSH
14 #define FELKELCOMPONENTSH
29 #pragma warning(disable: 4786) // prevent common warning about templates
35 #define CN_PI ((CNumber ) 3.14159265358979323846)
38 #define CN_INFINITY ((CNumber ) DBL_MAX)
40 #define CN_INFINITY ((CNumber ) 1.797693E+308)
42 #define CN_SLOPE_MAX ((CNumber ) CN_PI * 89 /180)
43 #define CN_SLOPE_MIN ((CNumber ) CN_PI / 180)
45 #define MIN_DIFF 0.00005 // For vtp this gives about a 5 cm resolution
46 #define MIN_ANGLE_DIFF 0.00005
48 #define SIMILAR(a,b) ((a)-(b) < MIN_DIFF && (b)-(a) < MIN_DIFF)
49 #define ANGLE_SIMILAR(a,b) (a.NormalizedAngle() - b.NormalizedAngle() < MIN_ANGLE_DIFF && b.NormalizedAngle() - a.NormalizedAngle() < MIN_ANGLE_DIFF)
59 CNumber& operator = (
const CNumber &x) { m_n = x.m_n;
return *
this; }
60 CNumber& operator = (
const double &x) { m_n = x;
return *
this; }
61 operator double& (void)
const {
return (
double &) m_n; }
62 bool operator == (
const CNumber &x)
const {
return SIMILAR (m_n, x.m_n); }
63 bool operator != (
const CNumber &x)
const {
return !SIMILAR (m_n, x.m_n); }
64 bool operator <= (
const CNumber &x)
const {
return m_n < x.m_n || *
this == x; }
65 bool operator >= (
const CNumber &x)
const {
return m_n > x.m_n || *
this == x; }
66 bool operator < (
const CNumber &x)
const {
return m_n < x.m_n && *
this != x; }
67 bool operator > (
const CNumber &x)
const {
return m_n > x.m_n && *
this != x; }
69 bool operator == (
const double x)
const {
return *
this ==
CNumber (x); }
70 bool operator != (
const double x)
const {
return *
this !=
CNumber (x); }
71 bool operator <= (
const double x)
const {
return *
this <=
CNumber (x); }
72 bool operator >= (
const double x)
const {
return *
this >=
CNumber (x); }
73 bool operator < (
const double x)
const {
return *
this <
CNumber (x); }
74 bool operator > (
const double x)
const {
return *
this >
CNumber (x); }
91 C3DPoint (
void) : m_x(0), m_y(0), m_z(0) { }
93 bool operator == (
const C3DPoint &p)
const
95 if (m_x == p.m_x && m_z == p.m_z && m_y == p.m_y)
100 if (m_x == p.m_x && m_z == p.m_z)
101 VTLOG(
"C3DPoint - 2D equality not maintained y1 %e y2 %e\n", m_y, p.m_y);
106 bool operator != (
const C3DPoint &p)
const
108 if (m_x != p.m_x || m_z != p.m_z || m_y != p.m_y)
111 if (m_x == p.m_x && m_z == p.m_z)
112 VTLOG(
"C3DPoint - 2D inequality not maintained y1 %e y2 %e\n", m_y, p.m_y);
122 bool IsInfiniteXZ (
void) {
return *
this ==
C3DPoint (CN_INFINITY, CN_INFINITY, CN_INFINITY) ?
true :
false; }
123 CNumber DistXZ(
const C3DPoint &p)
const {
return sqrt ((m_x-p.m_x)*(m_x-p.m_x) + (m_z - p.m_z)*(m_z - p.m_z));}
124 CNumber LengthXZ() {
return sqrt (m_x * m_x + m_z * m_z);}
125 CNumber DotXZ(
const C3DPoint &p)
const {
return m_x * p.m_x + m_z * p.m_z; }
126 CNumber CrossXZ(
const C3DPoint &p) {
return (m_x * p.m_z - m_z * p.m_x);}
136 m_Point(X, Y, Z), m_Slope(Slope), m_pMaterial(pMaterial), m_Color(Color) {};
137 bool operator == (
const CEdge &p)
const {
return m_Point == p.m_Point; }
144 typedef vector <CEdge> Contour;
145 typedef vector <Contour> ContourVector;
151 CRidgeLine(
const C3DPoint &p,
const CNumber &a,
const CNumber &Slope,
const bool IsRidgeLine =
true) : m_Origin (p), m_Angle (a), m_Slope(Slope), m_IsRidgeLine(IsRidgeLine)
153 m_Angle.NormalizeAngle();
155 CRidgeLine Opaque(
void)
const {
return CRidgeLine (m_Origin, m_Angle + CN_PI, m_Slope, m_IsRidgeLine); }
160 inline bool PointOnRidgeLine (
const C3DPoint &p)
const
162 return (p == m_Origin ||
CRidgeLine(m_Origin, p, -1).m_Angle == m_Angle) ?
true :
false;
164 inline bool FacingTowards (
const CRidgeLine &a)
const
167 if (m_IsRidgeLine != a.m_IsRidgeLine)
168 VTLOG(
"%s %d m_IsRidgeLine %d\n", __FILE__, __LINE__, m_IsRidgeLine);
171 if (a.PointOnRidgeLine(m_Origin) && PointOnRidgeLine(a.m_Origin) && !(m_Origin == a.m_Origin) && SIMILAR(m_Slope, 0.0) && SIMILAR(m_Slope, 0.0))
173 VTLOG(
"Forcing return false\n");
178 return (a.PointOnRidgeLine(m_Origin) && PointOnRidgeLine(a.m_Origin) && !(m_Origin == a.m_Origin)) ?
true :
false;
196 CVertex (
void) : m_ID (-1) { };
198 : m_point (p), m_axis (CRidgeLine::AngleAxis (p, prev, prevslope, next, nextslope)), m_leftLine (p, prev, prevslope), m_rightLine (p, next, nextslope), m_higher (NULL),
199 m_leftVertex (NULL), m_rightVertex (NULL), m_nextVertex (NULL), m_prevVertex (NULL), m_done (
false), m_ID (-1),
200 m_leftSkeletonLine (NULL), m_rightSkeletonLine (NULL), m_advancingSkeletonLine (NULL) { }
202 CVertex *Highest (
void) {
return m_higher ? m_higher -> Highest () :
this; }
203 bool AtContour (
void)
const {
return m_leftVertex ==
this && m_rightVertex ==
this; }
204 bool operator == (
const CVertex &v)
const {
return m_point == v.m_point; }
205 bool operator < (
const CVertex &)
const { VTLOG(
"%s %d Assert failed\n", __FILE__, __LINE__);
return false; }
210 bool VertexInCurrentContour(
CVertex& Vertex);
215 CVertex *m_leftVertex, *m_rightVertex;
216 CVertex *m_nextVertex, *m_prevVertex;
231 iterator prev (
const iterator &i) { iterator tmp (i);
if (tmp == begin ()) tmp = end (); tmp --;
return tmp; }
232 iterator next (
const iterator &i) { iterator tmp (i); tmp ++;
if (tmp == end ()) tmp = begin ();
return tmp; }
233 void push_back (
const CVertex& x)
236 if (!(x.m_prevVertex == NULL || x.m_leftLine.FacingTowards (x.m_prevVertex -> m_rightLine)))
237 VTLOG(
"%s %d Assert failed\n", __FILE__, __LINE__);
238 if (!(x.m_nextVertex == NULL || x.m_rightLine.FacingTowards (x.m_nextVertex -> m_leftLine)))
239 VTLOG(
"%s %d Assert failed\n", __FILE__, __LINE__);
242 list <CVertex> :: push_back (x);
244 VTLOG(
"Vertex %d x %f y %f z %f ridge angle %f ridge slope %f\n left %d right %d prev %d next %d added to list\n",
248 (((
CVertex &)x).m_leftVertex == NULL) ? -999 : ((
CVertex &)x).m_leftVertex->m_ID,
249 (((
CVertex &)x).m_rightVertex == NULL) ? -999 : ((
CVertex &)x).m_rightVertex->m_ID,
250 (((
CVertex &)x).m_prevVertex == NULL) ? -999 : ((
CVertex &)x).m_prevVertex->m_ID,
251 (((
CVertex &)x).m_nextVertex == NULL) ? -999 : ((
CVertex &)x).m_nextVertex->m_ID);
256 VTLOG(
"Dumping Vertex list\n");
257 for (iterator i = begin(); i != end(); i++)
259 VTLOG(
"Vertex %d x %e y %e z %e ridge angle %e ridge slope %e left %d right %d prev %d next\n",
261 (
double) (*i).m_point.m_x, (
double) (*i).m_point.m_y, (
double) (*i).m_point.m_z,
262 (
double) (*i).m_axis.m_Angle, (
double) (*i).m_axis.m_Slope,
263 ((*i).m_leftVertex == NULL) ? -999 : (*i).m_leftVertex->m_ID,
264 ((*i).m_rightVertex == NULL) ? -999 : (*i).m_rightVertex->m_ID,
265 ((*i).m_prevVertex == NULL) ? -999 : (*i).m_prevVertex->m_ID,
266 ((*i).m_nextVertex == NULL) ? -999 : (*i).m_nextVertex->m_ID);
268 VTLOG(
"Vertex list dump complete\n");
289 operator CSegment (
void) {
return CSegment (m_lower.m_vertex -> m_point, m_higher.m_vertex -> m_point); }
296 int LeftID (
void)
const {
if (!m_left)
return -1;
return m_left -> m_ID; }
297 int RightID (
void)
const {
if (!m_right)
return -1;
return m_right -> m_ID; }
298 int VertexID (
void)
const {
if (!m_vertex)
return -1;
return m_vertex -> m_ID; }
302 return m_higher.m_vertex -> m_ID == s.m_higher.m_vertex -> m_ID && m_lower.m_vertex -> m_ID == s.m_lower.m_vertex -> m_ID ;
304 bool operator < (
const CSkeletonLine &)
const { VTLOG(
"%s %d Assert failed\n", __FILE__, __LINE__);
return false; }
317 VTLOG(
"New skeleton line %d lower %d higher %d\n",
323 list <CSkeletonLine> :: push_back (x);
327 #endif // FELKELCOMPONENTSH