xform_2d.cpp

Go to the documentation of this file.
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