From: Mikko L. <laz...@us...> - 2004-06-15 19:14:08
|
Update of /cvsroot/rtk/rtk/src/gui In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5378 Added Files: Matrix.cpp Log Message: Added 3x3 (2D) Matrix class --- NEW FILE: Matrix.cpp --- /** * * RTK * Fast and easy cross-platform GUI ToolKit. * * Copyright (C) 2001-200x RTK Development Team * * This library is free software; you can redistribute it and/or modify it * under the terms of the slightly modified (see the "EXCEPTION NOTICE" part * of RTK Library License) GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * and along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA . * * Also you should have received a copy of RTK Library License, if not please * write an e-mail to some of RTK authors (listed in file AUTHORS). * * Bug reports: bu...@rt... * Suggestions: rf...@rt... ***************************************************************************/ /** * $Source: /cvsroot/rtk/rtk/src/gui/Matrix.cpp,v $ ***** * Authors (chronological order): * Mikko Lahteenmaki, mikko§rtk.cx * Contributors (chronological order): * $fname $lname, $email ***** * T0D0 List: * - ***************************************************************************/ /** * @file * Implementation of the 3x3 (2D) Matrix */ #include <rtk/Matrix.h> #include <math.h> namespace Rtk { #ifndef floorf # define floorf(x) ((float)floor((double)(x))) #endif Matrix& Matrix::copy(const Matrix &m) { m11 = m.m11; m12 = m.m12; m21 = m.m21; m22 = m.m22; x = m.x; y = m.y; ix = m.ix; iy = m.iy; trivial = m.trivial; return *this; } void Matrix::set_matrix(float M11, float M12, float M21, float M22, float X, float Y, bool trivial) { m11 = M11; m12 = M12; m21 = M12; m22 = M22; x = X; y = Y; ix = int(floorf(X+.5f)); iy = int(floorf(Y+.5f)); trivial = trivial; } void Matrix::translate(float dx, float dy) { if(trivial) { x += dx; y += dy; ix = int(floorf(x+.5f)); iy = int(floorf(y+.5f)); trivial = (ix==x && iy==y); } else { x += dx * m11 + dy * m21; y += dy * m22 + dx * m12; ix = int(floorf(x+.5f)); iy = int(floorf(y+.5f)); } } void Matrix::translate(int dx, int dy) { if(trivial) { ix += dx; iy += dy; x = float(ix); y = float(iy); } else { x += dx * m11 + dy * m21; y += dy * m22 + dx * m12; ix = int(floorf(x+.5f)); iy = int(floorf(y+.5f)); } } void Matrix::transform(float &dx, float &dy) const { if(!trivial) { float nx = m11*dx + m21*dy + x; float ny = m12*dx + m22*dy + y; dx = nx; dy = ny; } else { dx += x; dy += y; } } void Matrix::transform(int &dx, int &dy) const { if(!trivial) { int nx = int(floorf(m11*dx + m21*dy + x + .5f)); int ny = int(floorf(m12*dx + m22*dy + y + .5f)); dx = nx; dy = ny; } else { dx += ix; dy += iy; } } void Matrix::transform_distance(float &dx, float &dy) const { if(trivial) return; float nx = m11*dx + m21*dy; float ny = m12*dx + m22*dy; dx = nx; dy = ny; } void Matrix::rotate(float degrees) { float s, c; // sin & cos if(degrees==0) { s = 0; c = 1; } else if(degrees==90) { s = 1; c = 0; } else if(degrees==180) { s = 0; c = -1; } else if(degrees==270 || degrees==-90) { s = -1; c = 0; } else { float rad = DEG2RAD * degrees; // Convert to radians s = sinf(rad); c = cosf(rad); } //multiply(c, -s, s, c, 0, 0); float t00 = c * m11 + -s * m21; float t01 = c * m12 + -s * m22; float t10 = s * m11 + c * m21; float t11 = s * m12 + c * m22; m11 = t00; m12 = t01; m21 = t10; m22 = t11; trivial = false; } void Matrix::scale(float factor_x, float factor_y) { if(factor_x != 1.0f) { m11 *= factor_x; m12 *= factor_x; trivial = false; } if(factor_y != 1.0f) { m21 *= factor_y; m22 *= factor_y; trivial = false; } } void Matrix::shear(float factor_h, float factor_v) { float t11 = factor_v * m21; float t12 = factor_v * m22; float t21 = factor_h * m11; float t22 = factor_h * m12; m11 += t11; m12 += t12; m21 += t21; m22 += t22; trivial = false; } // Multiply this matrix by given values. void Matrix::multiply(float M11, float M12, float M21, float M22, float X, float Y) { if(trivial) { m11 = M11; m12 = M12; m21 = M21; m22 = M22; x += X; y += Y; ix = int(floor(x+.5f)); iy = int(floor(y+.5f)); trivial = false; } else { float t00 = M11 * m11 + M12 * m21; float t01 = M11 * m12 + M12 * m22; float t10 = M21 * m11 + M22 * m21; float t11 = M21 * m12 + M22 * m22; if(X!=0) { x = X * m11 + Y * m21 + x; ix = int(floor(x+.5f)); } if(Y!=0) { y = X * m12 + Y * m22 + y; iy = int(floor(y+.5f)); } m11 = t00; m12 = t01; m21 = t10; m22 = t11; trivial = false; } } }; // namespace Rtk |