00001 /* 00002 * xform_2d.cpp 00003 * 00004 * Copyright (C) 2007 Thomas A. Vaughan 00005 * All rights reserved. 00006 * 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions are met: 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * * Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in the 00014 * documentation and/or other materials provided with the distribution. 00015 * * Neither the name of the <organization> nor the 00016 * names of its contributors may be used to endorse or promote products 00017 * derived from this software without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THOMAS A. VAUGHAN ''AS IS'' AND ANY 00020 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00022 * DISCLAIMED. IN NO EVENT SHALL THOMAS A. VAUGHAN BE LIABLE FOR ANY 00023 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00026 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 * 00030 * 00031 * Implementation of transforms. 00032 */ 00033 00034 // includes -------------------------------------------------------------------- 00035 #include "xform_2d.h" // always include our own header first! 00036 00037 #include "perf/perf.h" 00038 00039 00040 void 00041 xform_2d_t::transformRect 00042 ( 00043 IN const rect_t& in, 00044 OUT rect_t& out 00045 ) 00046 const throw() 00047 { 00048 // this routine is so fast the timer impacts the performance! 00049 // only enable timer for debugging 00050 // perf::Timer timer("xform_2d_t::transformRect"); 00051 00052 // DPRINTF("in transformRect()"); 00053 00054 point_t p[4]; 00055 p[0].x = in.left; p[0].y = in.top; 00056 p[1].x = in.left; p[1].y = in.bottom; 00057 p[2].x = in.right; p[2].y = in.top; 00058 p[3].x = in.right; p[3].y = in.bottom; 00059 00060 point_t q; 00061 this->transformPoint(p[0], q); 00062 out.left = out.right = q.x; 00063 out.top = out.bottom = q.y; 00064 00065 for (int i = 0; i < 4; ++i) { 00066 this->transformPoint(p[i], q); 00067 // DPRINTF(" (%5.2f, %5.2f) --> (%5.2f, %5.2f)", 00068 // p[i].x, p[i].y, q.x, q.y); 00069 00070 if (q.x < out.left) 00071 out.left = q.x; 00072 if (q.x > out.right) 00073 out.right = q.x; 00074 if (q.y < out.top) 00075 out.top = q.y; 00076 if (q.y > out.bottom) 00077 out.bottom = q.y; 00078 } 00079 } 00080 00081 00082 00083 //////////////////////////////////////////////////////////////////////////////// 00084 // 00085 // Matrix inversion 00086 // 00087 // See my 3 March 2007 journal entry. 00088 // 00089 // Basically, | R d | 00090 // T = | 0 1 | 00091 // 00092 // Where R is a 2x2 matrix (rotation and scaling), and d is a 2d column 00093 // vector (x,y displacement). The inverse of T = inv(T) = 00094 // 00095 // | inv(R) -inv(R) d | 00096 // inv(T) = | 0 1 | 00097 // 00098 // | 1 0 0 | 00099 // so T * inv(T) = inv(T) * T = | 0 1 0 | 00100 // | 0 0 1 | 00101 // 00102 //////////////////////////////////////////////////////////////////////////////// 00103 void 00104 xform_2d_t::setToInverseOf 00105 ( 00106 IN const xform_2d_t& T 00107 ) 00108 throw() 00109 { 00110 // get the determinant 00111 float det = T.t00 * T.t11 - T.t01 * T.t10; 00112 ASSERT(det, "Taking the inverse of a matrix with null determinant"); 00113 float inv_det = 1.0 / det; 00114 00115 // the rotation part is a straightforward inverse (see above) 00116 t00 = inv_det * T.t11; 00117 t11 = inv_det * T.t00; 00118 t01 = -inv_det * T.t01; 00119 t10 = -inv_det * T.t10; 00120 00121 // inverse displacement (see above) 00122 dx = -inv_det * (T.t11 * T.dx - T.t01 * T.dy); 00123 dy = -inv_det * (T.t00 * T.dy - T.t10 * T.dx); 00124 } 00125