00001
00020 #ifndef INC_MI32_FILLPOLY_H
00021 #define INC_MI32_FILLPOLY_H
00022
00023 #ifndef INC_MI32_POINT_H
00024 #include <mi32/point.h>
00025 #endif
00026
00027 #ifndef GENERATING_DOXYGEN_OUTPUT
00028 class POLYLINE;
00029 class SUBREGION2D;
00030 #endif
00031
00033 class FILLPOLYGON {
00034 public:
00035
00037 class SPAN {
00038 public:
00039 void Process (const double x1, const double x2, const double y)
00040 { VProcess(x1,x2,y); }
00041 private:
00042 virtual void VProcess (const double x1, const double x2, const double y) = 0;
00043 };
00044
00047 static ERRVALUE MakeScans (
00048 const POLYLINE& polyline,
00049 SPAN& span,
00050 const double origin = 0.0,
00051 const double step = 1.0
00052 );
00053
00056 static ERRVALUE MakeScans (
00057 const SUBREGION2D& subregion,
00058 SPAN& span,
00059 const double origin = 0.0,
00060 const double step = 1.0
00061 );
00062
00063 private:
00064 #ifndef GENERATING_DOXYGEN_OUTPUT
00065
00066 class EDGE {
00067 public:
00068
00069 EDGE (
00070 const DPOINT2D& p1,
00071 const DPOINT2D& p2
00072 ) :
00073 m_YMin(MIN(p1.y,p2.y)),
00074 m_YMax(MAX(p1.y,p2.y)),
00075 m_DX((p1.y != p2.y) ? (p2.x - p1.x) / (p2.y - p1.y) : 0.0),
00076 m_X((p1.y < p2.y) ? p1.x : p2.x)
00077 { }
00078
00079 EDGE& operator= (
00080 const EDGE& rhs
00081 ) {
00082 if (this != &rhs) {
00083 const_cast<double&>(m_YMin) = rhs.m_YMin;
00084 const_cast<double&>(m_YMax) = rhs.m_YMax;
00085 const_cast<double&>(m_DX) = rhs.m_DX;
00086 m_X = rhs.m_X;
00087 }
00088 return (*this);
00089 }
00090
00091 bool IsHorizontal (
00092 ) const {
00093 return (m_YMin == m_YMax);
00094 }
00095
00096 void SetX (
00097 const double y
00098 ) {
00099 m_X += m_DX * (y - m_YMin);
00100 return;
00101 }
00102
00103 double GetX (
00104 ) {
00105 return m_X;
00106 }
00107
00108 void UpdateX (
00109 ) {
00110 m_X += m_DX;
00111 return;
00112 }
00113
00114 const double m_YMin;
00115 const double m_YMax;
00116 const double m_DX;
00117
00118 private:
00119 double m_X;
00120 };
00121
00122 static int DoubleLessCompare (
00123 const void *p1,
00124 const void *p2
00125 ) {
00126 const double *d1 = static_cast<const double*>(p1);
00127 const double *d2 = static_cast<const double*>(p2);
00128
00129 if (*d1 > *d2) return 1;
00130 if (*d1 < *d2) return -1;
00131 return 0;
00132 };
00133
00134 static int EdgeYMinGreaterCompare (
00135 const void *p1,
00136 const void *p2
00137 ) {
00138 const EDGE *d1 = static_cast<const EDGE*>(p1);
00139 const EDGE *d2 = static_cast<const EDGE*>(p2);
00140
00141 if (d1->m_YMin < d2->m_YMin) return 1;
00142 if (d1->m_YMin > d2->m_YMin) return -1;
00143 return 0;
00144 };
00145
00147 FILLPOLYGON();
00148 ~FILLPOLYGON();
00149 FILLPOLYGON(const FILLPOLYGON&);
00150
00151 #endif // GENERATING_DOXYGEN_OUTPUT
00152
00153 };
00154
00155 #endif // INC_MI32_FILLPOLY_H