00001
00030 #ifndef INC_MI32_QUANTIZER_H
00031 #define INC_MI32_QUANTIZER_H
00032
00033 #ifndef INC_MI32_POINT_H
00034 #include <mi32/point.h>
00035 #endif
00036
00037
00038
00041 class QUANTIZER_VALUES {
00042 public:
00043
00045 QUANTIZER_VALUES (
00046 ): m_ScaleQtoD(1), m_ScaleDtoQ(1), m_OffsetQtoD(0) { }
00047
00049 QUANTIZER_VALUES (
00050 double ScaleQtoD,
00051 double OffsetQtoD
00052 ): m_ScaleQtoD(ScaleQtoD), m_ScaleDtoQ(1.0/ScaleQtoD), m_OffsetQtoD(OffsetQtoD) { }
00053
00055 double CalcDouble (
00056 double ValueQ
00057 ) const { return (ValueQ * m_ScaleQtoD + m_OffsetQtoD); }
00058
00060 INT16 CalcPrecision () const
00061 {
00062 if (m_ScaleQtoD == 0) return (0);
00063 double iscale = floor(1.0 / fabs(m_ScaleQtoD) + .5);
00064 return (static_cast<INT16>(FAST_CEIL_NEARINT(log(iscale)/log(10.0))));
00065 }
00066
00068 double CalcRaw (
00069 double ValueD
00070 ) const { return ((ValueD - m_OffsetQtoD) * m_ScaleDtoQ); }
00071
00073 double GetScale () const
00074 { return (m_ScaleQtoD); }
00075
00077 double GetOffset () const
00078 { return (m_OffsetQtoD); }
00079
00081 void Set (
00082 double ScaleQtoD,
00083 double OffsetQtoD
00084 ) { SetScale(ScaleQtoD); SetOffset(OffsetQtoD); }
00085
00087 void SetScale (
00088 double ScaleQtoD
00089 ) { m_ScaleQtoD = ScaleQtoD; m_ScaleDtoQ = 1.0 / ScaleQtoD; }
00090
00092 void SetOffset (
00093 double OffsetQtoD
00094 ) { m_OffsetQtoD = OffsetQtoD; }
00095
00096 private:
00097 #ifndef GENERATING_DOXYGEN_OUTPUT
00098 double m_ScaleQtoD;
00099 double m_ScaleDtoQ;
00100 double m_OffsetQtoD;
00101 #endif
00102 };
00103
00104
00105
00107 template<typename _TypeQuantized> class QUANTIZER : public QUANTIZER_VALUES {
00108 public:
00109
00111 QUANTIZER ()
00112 { }
00113
00115 QUANTIZER (
00116 double ScaleQtoD,
00117 double OffsetQtoD
00118 ): QUANTIZER_VALUES(ScaleQtoD,OffsetQtoD) { }
00119
00122 _TypeQuantized CalcInt (
00123 double ValueD
00124 ) const { return (static_cast<_TypeQuantized>(FAST_ROUND_EXACT(CalcRaw(ValueD)))); }
00125
00126 };
00127
00128
00129
00131 class QUANTIZER_LPOINT2D {
00132 public:
00133
00135 QUANTIZER_LPOINT2D ()
00136 { }
00137
00139 QUANTIZER_LPOINT2D (
00140 double ScaleX,
00141 double ScaleY,
00142 double OffsetX,
00143 double OffsetY
00144 ): m_X(ScaleX,OffsetX), m_Y(ScaleY,OffsetY)
00145 { }
00146
00148 QUANTIZER_LPOINT2D (
00149 const DPOINT2D& Scale,
00150 const DPOINT2D& Offset
00151 ): m_X(Scale.x,Offset.x), m_Y(Scale.y,Offset.y)
00152 { }
00153
00155 DPOINT2D CalcDouble2D (
00156 const LPOINT2D& ptQ
00157 ) const { return (DPOINT2D(m_X.CalcDouble(ptQ.x),m_Y.CalcDouble(ptQ.y))); }
00158
00160 void CalcDouble2D (
00161 const LPOINT2D& ptQ,
00162 DPOINT2D& ptD
00163 ) const { ptD.x = m_X.CalcDouble(ptQ.x); ptD.y = m_Y.CalcDouble(ptQ.y); }
00164
00167 LPOINT2D CalcInt2D (
00168 const DPOINT2D& ptD
00169 ) const { return (LPOINT2D(m_X.CalcInt(ptD.x),m_Y.CalcInt(ptD.y))); }
00170
00173 void CalcInt2D (
00174 const DPOINT2D& ptD,
00175 LPOINT2D& ptQ
00176 ) const { ptQ.x = m_X.CalcInt(ptD.x); ptQ.y = m_Y.CalcInt(ptD.y); }
00177
00179 void CalcRaw2D (
00180 const DPOINT2D& ptD,
00181 DPOINT2D& ptRaw
00182 ) const { ptRaw.x = m_X.CalcRaw(ptD.x); ptRaw.y = m_Y.CalcRaw(ptD.y); }
00183
00185 const QUANTIZER<INT32>& GetX () const
00186 { return (m_X); }
00187
00189 const QUANTIZER<INT32>& GetY () const
00190 { return (m_Y); }
00191
00193 void Set2D (
00194 const DPOINT2D& Scale,
00195 const DPOINT2D& Offset
00196 ) { m_X.Set(Scale.x,Offset.x); m_Y.Set(Scale.y,Offset.y); }
00197
00199 void SetX (
00200 const QUANTIZER_VALUES& QuantX
00201 ) { m_X.Set(QuantX.GetScale(),QuantX.GetOffset()); }
00202
00204 void SetX (
00205 double ScaleX,
00206 double OffsetX
00207 ) { m_X.Set(ScaleX,OffsetX); }
00208
00210 void SetY (
00211 const QUANTIZER_VALUES& QuantY
00212 ) { m_Y.Set(QuantY.GetScale(),QuantY.GetOffset()); }
00213
00215 void SetY (
00216 double ScaleY,
00217 double OffsetY
00218 ) { m_Y.Set(ScaleY,OffsetY); }
00219
00220 private:
00221 #ifndef GENERATING_DOXYGEN_OUTPUT
00222 QUANTIZER<INT32> m_X;
00223 QUANTIZER<INT32> m_Y;
00224 #endif
00225 };
00226
00227
00228
00230 class QUANTIZER_LPOINT3D : public QUANTIZER_LPOINT2D {
00231 public:
00232
00234 QUANTIZER_LPOINT3D ()
00235 { }
00236
00238 QUANTIZER_LPOINT3D (
00239 double ScaleX,
00240 double ScaleY,
00241 double ScaleZ,
00242 double OffsetX,
00243 double OffsetY,
00244 double OffsetZ
00245 ): QUANTIZER_LPOINT2D(ScaleX,ScaleY,OffsetX,OffsetY), m_Z(ScaleZ,OffsetZ) { }
00246
00248 QUANTIZER_LPOINT3D (
00249 const DPOINT3D& Scale,
00250 const DPOINT3D& Offset
00251 ): QUANTIZER_LPOINT2D(Scale,Offset), m_Z(Scale.z,Offset.z) { }
00252
00254 DPOINT3D CalcDouble3D (
00255 const LPOINT3D& ptQ
00256 ) const { return (DPOINT3D(GetX().CalcDouble(ptQ.x),GetY().CalcDouble(ptQ.y),m_Z.CalcDouble(ptQ.z))); }
00257
00259 void CalcDouble3D (
00260 const LPOINT3D& ptQ,
00261 DPOINT3D& ptD
00262 ) const { ptD.x = GetX().CalcDouble(ptQ.x); ptD.y = GetY().CalcDouble(ptQ.y); ptD.z = m_Z.CalcDouble(ptQ.z); }
00263
00266 LPOINT3D CalcInt3D (
00267 const DPOINT3D& ptD
00268 ) const { return (LPOINT3D(GetX().CalcInt(ptD.x),GetY().CalcInt(ptD.y),m_Z.CalcInt(ptD.z))); }
00269
00272 void CalcInt3D (
00273 const DPOINT3D& ptD,
00274 LPOINT3D& ptQ
00275 ) const { ptQ.x = GetX().CalcInt(ptD.x); ptQ.y = GetY().CalcInt(ptD.y); ptQ.z = m_Z.CalcInt(ptD.z); }
00276
00278 void CalcRaw3D (
00279 const DPOINT3D& ptD,
00280 DPOINT3D& ptRaw
00281 ) const { CalcRaw2D(ptD,ptRaw); ptRaw.z = m_Z.CalcRaw(ptD.z); }
00282
00284 const QUANTIZER<INT32>& GetZ () const
00285 { return (m_Z); }
00286
00288 void Set3D (
00289 const DPOINT3D& Scale,
00290 const DPOINT3D& Offset
00291 ) { Set2D(Scale,Offset); m_Z.Set(Scale.z,Offset.z); }
00292
00294 void SetZ (
00295 const QUANTIZER_VALUES& QuantZ
00296 ) { m_Z.Set(QuantZ.GetScale(),QuantZ.GetOffset()); }
00297
00299 void SetZ (
00300 double ScaleZ,
00301 double OffsetZ
00302 ) { m_Z.Set(ScaleZ,OffsetZ); }
00303
00304 private:
00305 #ifndef GENERATING_DOXYGEN_OUTPUT
00306 QUANTIZER<INT32> m_Z;
00307 #endif
00308 };
00309
00310
00311
00312 #endif // INC_MI32_QUANTIZER_H