00001
00015 #include <dlrNumeric/transform3D.h>
00016
00017 namespace dlr {
00018
00019 namespace numeric {
00020
00021
00022 Transform3D::
00023 Transform3D(const Array2D<double>& source)
00024 {
00025 if((source.rows() != 4) || (source.columns() != 4)) {
00026 std::ostringstream message;
00027 message << "Can't create a Transform3D from a " << source.rows()
00028 << " x " << source.columns() << "Array2D<double> instance.";
00029 DLR_THROW(ValueException, "Transform3D::Transform3D()",
00030 message.str().c_str());
00031 }
00032 m_00 = source(0); m_01 = source(1); m_02 = source(2); m_03 = source(3);
00033 m_10 = source(4); m_11 = source(5); m_12 = source(6); m_13 = source(7);
00034 m_20 = source(8); m_21 = source(9); m_22 = source(10); m_23 = source(11);
00035 m_30 = source(12); m_31 = source(13); m_32 = source(14);
00036 this->normalize(source(15));
00037 }
00038
00039
00040
00041
00042
00043 Transform3DFunctor
00044 Transform3D::
00045 getFunctor() const {
00046 return Transform3DFunctor(*this);
00047 }
00048
00049
00050
00051 Transform3D
00052 Transform3D::
00053 invert() const
00054 {
00055
00056
00057
00058
00059
00060
00061
00062
00063 double det1201 = m_10 * m_21 - m_11 * m_20;
00064 double det1202 = m_10 * m_22 - m_12 * m_20;
00065 double det1203 = m_10 * m_23 - m_13 * m_20;
00066 double det1212 = m_11 * m_22 - m_12 * m_21;
00067 double det1213 = m_11 * m_23 - m_13 * m_21;
00068 double det1223 = m_12 * m_23 - m_13 * m_22;
00069
00070 double det1301 = m_10 * m_31 - m_11 * m_30;
00071 double det1302 = m_10 * m_32 - m_12 * m_30;
00072 double det1303 = m_10 - m_13 * m_30;
00073 double det1312 = m_11 * m_32 - m_12 * m_31;
00074 double det1313 = m_11 - m_13 * m_31;
00075 double det1323 = m_12 - m_13 * m_32;
00076
00077 double det2301 = m_20 * m_31 - m_21 * m_30;
00078 double det2302 = m_20 * m_32 - m_22 * m_30;
00079 double det2303 = m_20 - m_23 * m_30;
00080 double det2312 = m_21 * m_32 - m_22 * m_31;
00081 double det2313 = m_21 - m_23 * m_31;
00082 double det2323 = m_22 - m_23 * m_32;
00083
00084 double det012012 = (m_00 * det1212 - m_01 * det1202 + m_02 * det1201);
00085 double det012013 = (m_00 * det1213 - m_01 * det1203 + m_03 * det1201);
00086 double det012023 = (m_00 * det1223 - m_02 * det1203 + m_03 * det1202);
00087 double det012123 = (m_01 * det1223 - m_02 * det1213 + m_03 * det1212);
00088
00089 double det013012 = (m_00 * det1312 - m_01 * det1302 + m_02 * det1301);
00090 double det013013 = (m_00 * det1313 - m_01 * det1303 + m_03 * det1301);
00091 double det013023 = (m_00 * det1323 - m_02 * det1303 + m_03 * det1302);
00092 double det013123 = (m_01 * det1323 - m_02 * det1313 + m_03 * det1312);
00093
00094 double det023012 = (m_00 * det2312 - m_01 * det2302 + m_02 * det2301);
00095 double det023013 = (m_00 * det2313 - m_01 * det2303 + m_03 * det2301);
00096 double det023023 = (m_00 * det2323 - m_02 * det2303 + m_03 * det2302);
00097 double det023123 = (m_01 * det2323 - m_02 * det2313 + m_03 * det2312);
00098
00099 double det123012 = (m_10 * det2312 - m_11 * det2302 + m_12 * det2301);
00100 double det123013 = (m_10 * det2313 - m_11 * det2303 + m_13 * det2301);
00101 double det123023 = (m_10 * det2323 - m_12 * det2303 + m_13 * det2302);
00102 double det123123 = (m_11 * det2323 - m_12 * det2313 + m_13 * det2312);
00103
00104 double det01230123 = (
00105 m_00 * det123123 - m_01 * det123023
00106 + m_02 * det123013 - m_03 * det123012
00107 - m_10 * det023123 + m_11 * det023023
00108 - m_12 * det023013 + m_13 * det023012
00109 + m_20 * det013123 - m_21 * det013023
00110 + m_22 * det013013 - m_23 * det013012
00111 - m_30 * det012123 + m_31 * det012023
00112 - m_32 * det012013 + det012012);
00113
00114
00115
00116 if(det01230123 == 0.0) {
00117 DLR_THROW(ValueException, "Transform3D::invert()",
00118 "Transform is not invertible.");
00119 }
00120 if(det012012 == 0.0) {
00121 DLR_THROW(LogicException, "Transform3D::invert()",
00122 "Illegal value for projective scale.");
00123 }
00124
00125 return Transform3D(
00126 det123123 / det01230123, -det023123 / det01230123,
00127 det013123 / det01230123, -det012123 / det01230123,
00128 -det123023 / det01230123, det023023 / det01230123,
00129 -det013023 / det01230123, det012023 / det01230123,
00130 det123013 / det01230123, -det023013 / det01230123,
00131 det013013 / det01230123, -det012013 / det01230123,
00132 -det123012 / det01230123, det023012 / det01230123,
00133 -det013012 / det01230123, det012012 / det01230123);
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143 void
00144 Transform3D::
00145 setTransform(double a00, double a01, double a02, double a03,
00146 double a10, double a11, double a12, double a13,
00147 double a20, double a21, double a22, double a23,
00148 double a30, double a31, double a32, double a33)
00149 {
00150 m_00 = a00; m_01 = a01; m_02 = a02; m_03 = a03;
00151 m_10 = a10; m_11 = a11; m_12 = a12; m_13 = a13;
00152 m_20 = a20; m_21 = a21; m_22 = a22; m_23 = a23;
00153 m_30 = a30; m_31 = a31; m_32 = a32;
00154 this->normalize(a33);
00155 }
00156
00157
00158
00159
00160
00161 void
00162 Transform3D::
00163 setValue(size_t row, size_t column, double value)
00164 {
00165 switch(row) {
00166 case 0:
00167 switch(column) {
00168 case 0: m_00 = value; return; break;
00169 case 1: m_01 = value; return; break;
00170 case 2: m_02 = value; return; break;
00171 case 3: m_03 = value; return; break;
00172 default: break;
00173 }
00174 break;
00175 case 1:
00176 switch(column) {
00177 case 0: m_10 = value; return; break;
00178 case 1: m_11 = value; return; break;
00179 case 2: m_12 = value; return; break;
00180 case 3: m_13 = value; return; break;
00181 default: break;
00182 }
00183 break;
00184 case 2:
00185 switch(column) {
00186 case 0: m_20 = value; return; break;
00187 case 1: m_21 = value; return; break;
00188 case 2: m_22 = value; return; break;
00189 case 3: m_23 = value; return; break;
00190 default: break;
00191 }
00192 break;
00193 case 3:
00194 switch(column) {
00195 case 0: m_30 = value; return; break;
00196 case 1: m_31 = value; return; break;
00197 case 2: m_32 = value; return; break;
00198 default: break;
00199 }
00200 break;
00201 default:
00202 break;
00203 }
00204 std::ostringstream message;
00205 message << "Indices (" << row << ", " << column << ") are out of bounds.";
00206 DLR_THROW(IndexException, "Transform3D::operator()(size_t, size_t)",
00207 message.str().c_str());
00208 }
00209
00210
00211
00212
00213 double
00214 Transform3D::
00215 operator()(size_t row, size_t column) const
00216 {
00217
00218
00219 switch(row) {
00220 case 0:
00221 switch(column) {
00222 case 0: return m_00; break;
00223 case 1: return m_01; break;
00224 case 2: return m_02; break;
00225 case 3: return m_03; break;
00226 default: break;
00227 }
00228 break;
00229 case 1:
00230 switch(column) {
00231 case 0: return m_10; break;
00232 case 1: return m_11; break;
00233 case 2: return m_12; break;
00234 case 3: return m_13; break;
00235 default: break;
00236 }
00237 break;
00238 case 2:
00239 switch(column) {
00240 case 0: return m_20; break;
00241 case 1: return m_21; break;
00242 case 2: return m_22; break;
00243 case 3: return m_23; break;
00244 default: break;
00245 }
00246 break;
00247 case 3:
00248 switch(column) {
00249 case 0: return m_30; break;
00250 case 1: return m_31; break;
00251 case 2: return m_32; break;
00252 case 3: return 1.0; break;
00253 default: break;
00254 }
00255 break;
00256 default:
00257 break;
00258 }
00259 std::ostringstream message;
00260 message << "Indices (" << row << ", " << column << ") are out of bounds.";
00261 DLR_THROW(IndexException, "Transform3D::operator()(size_t, size_t)",
00262 message.str().c_str());
00263 return 0.0;
00264 }
00265
00266
00267
00268
00269 Vector3D
00270 Transform3D::
00271 operator*(const Vector3D& vector0) const
00272 {
00273 return Vector3D(
00274 m_00 * vector0.x() + m_01 * vector0.y() + m_02 * vector0.z() + m_03,
00275 m_10 * vector0.x() + m_11 * vector0.y() + m_12 * vector0.z() + m_13,
00276 m_20 * vector0.x() + m_21 * vector0.y() + m_22 * vector0.z() + m_23,
00277 m_30 * vector0.x() + m_31 * vector0.y() + m_32 * vector0.z() + 1.0);
00278 }
00279
00280
00281
00282 Transform3D&
00283 Transform3D::
00284 operator=(const Transform3D& source)
00285 {
00286 m_00 = source.m_00; m_01 = source.m_01;
00287 m_02 = source.m_02; m_03 = source.m_03;
00288 m_10 = source.m_10; m_11 = source.m_11;
00289 m_12 = source.m_12; m_13 = source.m_13;
00290 m_20 = source.m_20; m_21 = source.m_21;
00291 m_22 = source.m_22; m_23 = source.m_23;
00292 m_30 = source.m_30; m_31 = source.m_31;
00293 m_32 = source.m_32;
00294 return *this;
00295 }
00296
00297
00298 void
00299 Transform3D::
00300 normalize(double scaleFactor)
00301 {
00302 if(scaleFactor == 0.0) {
00303 DLR_THROW(ValueException, "Transform3D::normalize()",
00304 "Invalid normalization constant. "
00305 "The bottom right element of a homogeneous transformation "
00306 "cannot be equal to 0.0.");
00307 }
00308 if(scaleFactor != 1.0) {
00309 m_00 /= scaleFactor;
00310 m_01 /= scaleFactor;
00311 m_02 /= scaleFactor;
00312 m_03 /= scaleFactor;
00313 m_10 /= scaleFactor;
00314 m_11 /= scaleFactor;
00315 m_12 /= scaleFactor;
00316 m_13 /= scaleFactor;
00317 m_20 /= scaleFactor;
00318 m_21 /= scaleFactor;
00319 m_22 /= scaleFactor;
00320 m_23 /= scaleFactor;
00321 m_30 /= scaleFactor;
00322 m_31 /= scaleFactor;
00323 m_32 /= scaleFactor;
00324 }
00325 }
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 Transform3D
00336 operator*(const Transform3D& transform0, const Transform3D& transform1)
00337 {
00338 double a00 = (transform0.value<0, 0>() * transform1.value<0, 0>()
00339 + transform0.value<0, 1>() * transform1.value<1, 0>()
00340 + transform0.value<0, 2>() * transform1.value<2, 0>()
00341 + transform0.value<0, 3>() * transform1.value<3, 0>());
00342 double a01 = (transform0.value<0, 0>() * transform1.value<0, 1>()
00343 + transform0.value<0, 1>() * transform1.value<1, 1>()
00344 + transform0.value<0, 2>() * transform1.value<2, 1>()
00345 + transform0.value<0, 3>() * transform1.value<3, 1>());
00346 double a02 = (transform0.value<0, 0>() * transform1.value<0, 2>()
00347 + transform0.value<0, 1>() * transform1.value<1, 2>()
00348 + transform0.value<0, 2>() * transform1.value<2, 2>()
00349 + transform0.value<0, 3>() * transform1.value<3, 2>());
00350 double a03 = (transform0.value<0, 0>() * transform1.value<0, 3>()
00351 + transform0.value<0, 1>() * transform1.value<1, 3>()
00352 + transform0.value<0, 2>() * transform1.value<2, 3>()
00353 + transform0.value<0, 3>() * transform1.value<3, 3>());
00354 double a10 = (transform0.value<1, 0>() * transform1.value<0, 0>()
00355 + transform0.value<1, 1>() * transform1.value<1, 0>()
00356 + transform0.value<1, 2>() * transform1.value<2, 0>()
00357 + transform0.value<1, 3>() * transform1.value<3, 0>());
00358 double a11 = (transform0.value<1, 0>() * transform1.value<0, 1>()
00359 + transform0.value<1, 1>() * transform1.value<1, 1>()
00360 + transform0.value<1, 2>() * transform1.value<2, 1>()
00361 + transform0.value<1, 3>() * transform1.value<3, 1>());
00362 double a12 = (transform0.value<1, 0>() * transform1.value<0, 2>()
00363 + transform0.value<1, 1>() * transform1.value<1, 2>()
00364 + transform0.value<1, 2>() * transform1.value<2, 2>()
00365 + transform0.value<1, 3>() * transform1.value<3, 2>());
00366 double a13 = (transform0.value<1, 0>() * transform1.value<0, 3>()
00367 + transform0.value<1, 1>() * transform1.value<1, 3>()
00368 + transform0.value<1, 2>() * transform1.value<2, 3>()
00369 + transform0.value<1, 3>() * transform1.value<3, 3>());
00370 double a20 = (transform0.value<2, 0>() * transform1.value<0, 0>()
00371 + transform0.value<2, 1>() * transform1.value<1, 0>()
00372 + transform0.value<2, 2>() * transform1.value<2, 0>()
00373 + transform0.value<2, 3>() * transform1.value<3, 0>());
00374 double a21 = (transform0.value<2, 0>() * transform1.value<0, 1>()
00375 + transform0.value<2, 1>() * transform1.value<1, 1>()
00376 + transform0.value<2, 2>() * transform1.value<2, 1>()
00377 + transform0.value<2, 3>() * transform1.value<3, 1>());
00378 double a22 = (transform0.value<2, 0>() * transform1.value<0, 2>()
00379 + transform0.value<2, 1>() * transform1.value<1, 2>()
00380 + transform0.value<2, 2>() * transform1.value<2, 2>()
00381 + transform0.value<2, 3>() * transform1.value<3, 2>());
00382 double a23 = (transform0.value<2, 0>() * transform1.value<0, 3>()
00383 + transform0.value<2, 1>() * transform1.value<1, 3>()
00384 + transform0.value<2, 2>() * transform1.value<2, 3>()
00385 + transform0.value<2, 3>() * transform1.value<3, 3>());
00386 double a30 = (transform0.value<3, 0>() * transform1.value<0, 0>()
00387 + transform0.value<3, 1>() * transform1.value<1, 0>()
00388 + transform0.value<3, 2>() * transform1.value<2, 0>()
00389 + transform0.value<3, 3>() * transform1.value<3, 0>());
00390 double a31 = (transform0.value<3, 0>() * transform1.value<0, 1>()
00391 + transform0.value<3, 1>() * transform1.value<1, 1>()
00392 + transform0.value<3, 2>() * transform1.value<2, 1>()
00393 + transform0.value<3, 3>() * transform1.value<3, 1>());
00394 double a32 = (transform0.value<3, 0>() * transform1.value<0, 2>()
00395 + transform0.value<3, 1>() * transform1.value<1, 2>()
00396 + transform0.value<3, 2>() * transform1.value<2, 2>()
00397 + transform0.value<3, 3>() * transform1.value<3, 2>());
00398 double a33 = (transform0.value<3, 0>() * transform1.value<0, 3>()
00399 + transform0.value<3, 1>() * transform1.value<1, 3>()
00400 + transform0.value<3, 2>() * transform1.value<2, 3>()
00401 + transform0.value<3, 3>() * transform1.value<3, 3>());
00402 return Transform3D(a00, a01, a02, a03,
00403 a10, a11, a12, a13,
00404 a20, a21, a22, a23,
00405 a30, a31, a32, a33);
00406 }
00407
00408
00409 std::ostream&
00410 operator<<(std::ostream& stream, const Transform3D& transform0)
00411 {
00412 stream << "Transform3D("
00413 << transform0.value<0, 0>() << ", "
00414 << transform0.value<0, 1>() << ", "
00415 << transform0.value<0, 2>() << ", "
00416 << transform0.value<0, 3>() << ",\n"
00417 << transform0.value<1, 0>() << ", "
00418 << transform0.value<1, 1>() << ", "
00419 << transform0.value<1, 2>() << ", "
00420 << transform0.value<1, 3>() << ",\n"
00421 << transform0.value<2, 0>() << ", "
00422 << transform0.value<2, 1>() << ", "
00423 << transform0.value<2, 2>() << ", "
00424 << transform0.value<2, 3>() << ",\n"
00425 << transform0.value<3, 0>() << ", "
00426 << transform0.value<3, 1>() << ", "
00427 << transform0.value<3, 2>() << ", "
00428 << transform0.value<3, 3>() << ")";
00429 return stream;
00430 }
00431
00432 std::istream&
00433 operator>>(std::istream& stream, Transform3D& transform0)
00434 {
00435
00436 if (!stream){
00437 return stream;
00438 }
00439
00440
00441
00442
00443 std::ios_base::iostate oldExceptionState = stream.exceptions();
00444 stream.exceptions(
00445 std::ios_base::badbit | std::ios_base::failbit | std::ios_base::eofbit);
00446
00447
00448 try{
00449
00450
00451 InputStream inputStream(stream);
00452
00453
00454 inputStream.skipWhiteSpace();
00455
00456
00457 inputStream.expect("Transform3D(");
00458
00459
00460 std::vector<double> inputValues(16);
00461 for(size_t index = 0; index < (inputValues.size() - 1); ++index) {
00462
00463 inputStream >> inputValues[index];
00464
00465
00466 inputStream.expect(",");
00467 }
00468
00469
00470 inputStream >> inputValues[inputValues.size() - 1];
00471
00472
00473 inputStream.expect(")");
00474
00475
00476 transform0.setTransform(inputValues[0], inputValues[1],
00477 inputValues[2], inputValues[3],
00478 inputValues[4], inputValues[5],
00479 inputValues[6], inputValues[7],
00480 inputValues[8], inputValues[9],
00481 inputValues[10], inputValues[11],
00482 inputValues[12], inputValues[13],
00483 inputValues[14], inputValues[15]);
00484 } catch(std::ios_base::failure) {
00485
00486 }
00487 stream.exceptions(oldExceptionState);
00488 return stream;
00489 }
00490
00491 }
00492
00493 }