00001
00015 #include <dlrNumeric/transform2D.h>
00016
00017 namespace dlr {
00018
00019 namespace numeric {
00020
00021
00022 Transform2D::
00023 Transform2D(const Array2D<double>& source)
00024 {
00025 if((source.rows() != 3) || (source.columns() != 3)) {
00026 std::ostringstream message;
00027 message << "Can't create a Transform2D from a " << source.rows()
00028 << " x " << source.columns() << "Array2D<double> instance.";
00029 DLR_THROW(ValueException, "Transform2D::Transform2D()",
00030 message.str().c_str());
00031 }
00032 m_00 = source(0); m_01 = source(1); m_02 = source(2);
00033 m_10 = source(3); m_11 = source(4); m_12 = source(5);
00034 m_20 = source(6); m_21 = source(7);
00035 this->normalize(source(8));
00036 }
00037
00038
00039
00040
00041
00042 Transform2DFunctor
00043 Transform2D::
00044 getFunctor() const {
00045 return Transform2DFunctor(*this);
00046 }
00047
00048
00049
00050 Transform2D
00051 Transform2D::
00052 invert() const
00053 {
00054
00055
00056
00057
00058
00059
00060
00061
00062 double det0101 = m_00 * m_11 - m_01 * m_10;
00063 double det0102 = m_00 * m_12 - m_02 * m_10;
00064 double det0112 = m_01 * m_12 - m_02 * m_11;
00065
00066 double det0201 = m_00 * m_21 - m_01 * m_20;
00067 double det0202 = m_00 - m_02 * m_20;
00068 double det0212 = m_01 - m_02 * m_21;
00069
00070 double det1201 = m_10 * m_21 - m_11 * m_20;
00071 double det1202 = m_10 - m_12 * m_20;
00072 double det1212 = m_11 - m_12 * m_21;
00073
00074 double det012012 = (
00075 m_00 * det1212 - m_01 * det1202 + m_02 * det1201
00076 - m_10 * det0212 + m_11 * det0202 - m_12 * det0201
00077 + m_20 * det0112 - m_21 * det0102 + det0101);
00078
00079
00080
00081 if(det012012 == 0.0) {
00082 DLR_THROW(ValueException, "Transform2D::invert()",
00083 "Transform is not invertible.");
00084 }
00085 if(det0101 == 0.0) {
00086 DLR_THROW(LogicException, "Transform2D::invert()",
00087 "Illegal value for projective scale.");
00088 }
00089
00090 return Transform2D(
00091 det1212 / det012012, -det0212 / det012012, det0112 / det012012,
00092 -det1202 / det012012, det0202 / det012012, -det0102 / det012012,
00093 det1201 / det012012, -det0201 / det012012, det0101 / det012012);
00094 }
00095
00096
00097
00098
00099
00100
00101
00102 void
00103 Transform2D::
00104 setTransform(double a00, double a01, double a02,
00105 double a10, double a11, double a12,
00106 double a20, double a21, double a22)
00107 {
00108 m_00 = a00; m_01 = a01; m_02 = a02;
00109 m_10 = a10; m_11 = a11; m_12 = a12;
00110 m_20 = a20; m_21 = a21;
00111 this->normalize(a22);
00112 }
00113
00114
00115
00116
00117
00118 void
00119 Transform2D::
00120 setValue(size_t row, size_t column, double value)
00121 {
00122 switch(row) {
00123 case 0:
00124 switch(column) {
00125 case 0: m_00 = value; return; break;
00126 case 1: m_01 = value; return; break;
00127 case 2: m_02 = value; return; break;
00128 default: break;
00129 }
00130 break;
00131 case 1:
00132 switch(column) {
00133 case 0: m_10 = value; return; break;
00134 case 1: m_11 = value; return; break;
00135 case 2: m_12 = value; return; break;
00136 default: break;
00137 }
00138 break;
00139 case 2:
00140 switch(column) {
00141 case 0: m_20 = value; return; break;
00142 case 1: m_21 = value; return; break;
00143 default: break;
00144 }
00145 break;
00146 default:
00147 break;
00148 }
00149 std::ostringstream message;
00150 message << "Indices (" << row << ", " << column << ") are out of bounds.";
00151 DLR_THROW(IndexException, "Transform2D::operator()(size_t, size_t)",
00152 message.str().c_str());
00153 }
00154
00155
00156
00157
00158 double
00159 Transform2D::
00160 operator()(size_t row, size_t column) const
00161 {
00162
00163
00164 switch(row) {
00165 case 0:
00166 switch(column) {
00167 case 0: return m_00; break;
00168 case 1: return m_01; break;
00169 case 2: return m_02; break;
00170 default: break;
00171 }
00172 break;
00173 case 1:
00174 switch(column) {
00175 case 0: return m_10; break;
00176 case 1: return m_11; break;
00177 case 2: return m_12; break;
00178 default: break;
00179 }
00180 break;
00181 case 2:
00182 switch(column) {
00183 case 0: return this->value<2, 0>(); break;
00184 case 1: return m_21; break;
00185 case 2: return 1.0; break;
00186 default: break;
00187 }
00188 break;
00189 default:
00190 break;
00191 }
00192 std::ostringstream message;
00193 message << "Index (" << row << ", " << column << ") out of bounds.";
00194 DLR_THROW3(IndexException, "Transform2D::value()",
00195 message.str().c_str());
00196 return 0.0;
00197 }
00198
00199
00200
00201 Vector2D
00202 Transform2D::
00203 operator*(const Vector2D& vector0) const
00204 {
00205 return Vector2D(
00206 m_00 * vector0.x() + m_01 * vector0.y() + m_02,
00207 m_10 * vector0.x() + m_11 * vector0.y() + m_12,
00208 m_20 * vector0.x() + m_21 * vector0.y() + 1.0);
00209 }
00210
00211
00212 Transform2D&
00213 Transform2D::
00214 operator=(const Transform2D& source)
00215 {
00216 m_00 = source.m_00; m_01 = source.m_01; m_02 = source.m_02;
00217 m_10 = source.m_10; m_11 = source.m_11; m_12 = source.m_12;
00218 m_20 = source.m_20; m_21 = source.m_21;
00219 return *this;
00220 }
00221
00222 void
00223 Transform2D::
00224 normalize(double scaleFactor)
00225 {
00226 if(scaleFactor == 0.0) {
00227 DLR_THROW3(ValueException, "Trahnsform2D::normalize(double)",
00228 "Invalid normalization constant. "
00229 "The bottom right element of a homogeneous transformation "
00230 "cannot be equal to 0.0.");
00231 }
00232 if(scaleFactor != 1.0) {
00233 m_00 /= scaleFactor;
00234 m_01 /= scaleFactor;
00235 m_02 /= scaleFactor;
00236 m_10 /= scaleFactor;
00237 m_11 /= scaleFactor;
00238 m_12 /= scaleFactor;
00239 m_20 /= scaleFactor;
00240 m_21 /= scaleFactor;
00241 }
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 Transform2D
00253 operator*(const Transform2D& transform0, const Transform2D& transform1)
00254 {
00255 double a00 = (transform0.value<0, 0>() * transform1.value<0, 0>()
00256 + transform0.value<0, 1>() * transform1.value<1, 0>()
00257 + transform0.value<0, 2>() * transform1.value<2, 0>());
00258 double a01 = (transform0.value<0, 0>() * transform1.value<0, 1>()
00259 + transform0.value<0, 1>() * transform1.value<1, 1>()
00260 + transform0.value<0, 2>() * transform1.value<2, 1>());
00261 double a02 = (transform0.value<0, 0>() * transform1.value<0, 2>()
00262 + transform0.value<0, 1>() * transform1.value<1, 2>()
00263 + transform0.value<0, 2>() * transform1.value<2, 2>());
00264 double a10 = (transform0.value<1, 0>() * transform1.value<0, 0>()
00265 + transform0.value<1, 1>() * transform1.value<1, 0>()
00266 + transform0.value<1, 2>() * transform1.value<2, 0>());
00267 double a11 = (transform0.value<1, 0>() * transform1.value<0, 1>()
00268 + transform0.value<1, 1>() * transform1.value<1, 1>()
00269 + transform0.value<1, 2>() * transform1.value<2, 1>());
00270 double a12 = (transform0.value<1, 0>() * transform1.value<0, 2>()
00271 + transform0.value<1, 1>() * transform1.value<1, 2>()
00272 + transform0.value<1, 2>() * transform1.value<2, 2>());
00273 double a20 = (transform0.value<2, 0>() * transform1.value<0, 0>()
00274 + transform0.value<2, 1>() * transform1.value<1, 0>()
00275 + transform0.value<2, 2>() * transform1.value<2, 0>());
00276 double a21 = (transform0.value<2, 0>() * transform1.value<0, 1>()
00277 + transform0.value<2, 1>() * transform1.value<1, 1>()
00278 + transform0.value<2, 2>() * transform1.value<2, 1>());
00279 double a22 = (transform0.value<2, 0>() * transform1.value<0, 2>()
00280 + transform0.value<2, 1>() * transform1.value<1, 2>()
00281 + transform0.value<2, 2>() * transform1.value<2, 2>());
00282 return Transform2D(a00, a01, a02,
00283 a10, a11, a12,
00284 a20, a21, a22);
00285 }
00286
00287
00288 std::ostream&
00289 operator<<(std::ostream& stream, const Transform2D& transform0)
00290 {
00291 stream << "Transform2D("
00292 << transform0.value<0, 0>() << ", "
00293 << transform0.value<0, 1>() << ", "
00294 << transform0.value<0, 2>() << ", "
00295 << transform0.value<1, 0>() << ", "
00296 << transform0.value<1, 1>() << ", "
00297 << transform0.value<1, 2>() << ", "
00298 << transform0.value<2, 0>() << ", "
00299 << transform0.value<2, 1>() << ", "
00300 << transform0.value<2, 2>() << ")";
00301 return stream;
00302 }
00303
00304
00305 std::istream&
00306 operator>>(std::istream& stream, Transform2D& transform0)
00307 {
00308
00309 if (!stream){
00310 return stream;
00311 }
00312
00313
00314
00315
00316 std::ios_base::iostate oldExceptionState = stream.exceptions();
00317 stream.exceptions(
00318 std::ios_base::badbit | std::ios_base::failbit | std::ios_base::eofbit);
00319
00320
00321 try{
00322
00323
00324 InputStream inputStream(stream);
00325
00326
00327 inputStream.skipWhiteSpace();
00328
00329
00330 inputStream.expect("Transform2D(");
00331
00332
00333 std::vector<double> inputValues(9);
00334 for(size_t index = 0; index < (inputValues.size() - 1); ++index) {
00335
00336 inputStream >> inputValues[index];
00337
00338
00339 inputStream.expect(",");
00340 }
00341
00342
00343 inputStream >> inputValues[inputValues.size() - 1];
00344
00345
00346 inputStream.expect(")");
00347
00348
00349 transform0.setTransform(
00350 inputValues[0], inputValues[1], inputValues[2],
00351 inputValues[3], inputValues[4], inputValues[5],
00352 inputValues[6], inputValues[7], inputValues[8]);
00353
00354 } catch(std::ios_base::failure) {
00355
00356 }
00357 stream.exceptions(oldExceptionState);
00358 return stream;
00359 }
00360
00361 }
00362
00363 }