• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

plaffine.c

Go to the documentation of this file.
00001 // $Id: plaffine.c 11680 2011-03-27 17:57:51Z airwin $
00002 //
00003 // Affine manipulation routines for PLplot.
00004 //
00005 // Copyright (C) 2009  Alan W. Irwin
00006 //
00007 // This file is part of PLplot.
00008 //
00009 // PLplot is free software; you can redistribute it and/or modify
00010 // it under the terms of the GNU Library General Public License as published
00011 // by the Free Software Foundation; either version 2 of the License, or
00012 // (at your option) any later version.
00013 //
00014 // PLplot is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU Library General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU Library General Public License
00020 // along with PLplot; if not, write to the Free Software
00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00022 //
00023 //
00024 
00025 #include "plplotP.h"
00026 
00027 // For background on these affine functions see SVG specification, e.g.,
00028 // http://www.w3.org/TR/SVGTiny12/coords.html#EstablishingANewUserSpace.
00029 // Affine 3x3 matrices with elements A_i,j always have a last row of
00030 // 0, 0, 1 so the elements are conveniently stored in a vector in the order
00031 // A_1_1, A_2_1, A_1_2, A_2_2, A_1_3, A_2_3, with the last row implied.
00032 //
00033 // N.B.  The PLplot affine interpretation of translate, scale, etc., is
00034 // as actions on coordinate systems, rather than actions on objects.  This
00035 // is identical to the SVG specficiation interpretation.  However, the
00036 // SVG specification interprets the affine matrix as follows:
00037 // old_coord_vector = affine_matrix * new_coordinate vector.  In PLplot
00038 // we use the alternative interpretation
00039 // new_coord_vector = affine_matrix * old_coordinate vector.
00040 // The result is all affine matrices below are the inverses of the SVG
00041 // equivalents.
00042 //
00043 // N.B. All PLplot affine functions below return the affine matrix result (in
00044 // vector form) as the first argument).  It is the calling routine's
00045 // responsibility to provide the space for all affine matrix arguments,
00046 // i.e., a PLFLT array with a dimension of 6.
00047 //
00048 //
00049 
00050 // Returns affine identity matrix
00051 
00052 void
00053 plP_affine_identity( PLFLT *affine_vector )
00054 {
00055     affine_vector[0] = 1.;
00056     affine_vector[1] = 0.;
00057     affine_vector[2] = 0.;
00058     affine_vector[3] = 1.;
00059     affine_vector[4] = 0.;
00060     affine_vector[5] = 0.;
00061 }
00062 
00063 // Translate new coordinate system axes relative to the old.
00064 
00065 void
00066 plP_affine_translate( PLFLT *affine_vector, PLFLT xtranslate, PLFLT ytranslate )
00067 {
00068     affine_vector[0] = 1.;
00069     affine_vector[1] = 0.;
00070     affine_vector[2] = 0.;
00071     affine_vector[3] = 1.;
00072     // If the new coordinate system axis is shifted by xtranslate and ytranslate
00073     // relative to the old, then the actual new coordinates are shifted in
00074     // the opposite direction.
00075     affine_vector[4] = -xtranslate;
00076     affine_vector[5] = -ytranslate;
00077 }
00078 
00079 // Scale new coordinate system axes relative to the old.
00080 
00081 void
00082 plP_affine_scale( PLFLT *affine_vector, PLFLT xscale, PLFLT yscale )
00083 {
00084     // If the new coordinate system axes are scaled by xscale and yscale
00085     // relative to the old, then the actual new coordinates are scaled
00086     // by the inverses.
00087     if ( xscale == 0. )
00088     {
00089         plwarn( "plP_affine_scale: attempt to scale X coordinates by zero." );
00090         xscale = 1.;
00091     }
00092     if ( yscale == 0. )
00093     {
00094         plwarn( "plP_affine_scale: attempt to scale Y coordinates by zero." );
00095         yscale = 1.;
00096     }
00097     affine_vector[0] = 1. / xscale;
00098     affine_vector[1] = 0.;
00099     affine_vector[2] = 0.;
00100     affine_vector[3] = 1. / yscale;
00101     affine_vector[4] = 0.;
00102     affine_vector[5] = 0.;
00103 }
00104 
00105 // Rotate new coordinate system axes relative to the old.
00106 // angle is in degrees.
00107 
00108 void
00109 plP_affine_rotate( PLFLT *affine_vector, PLFLT angle )
00110 {
00111     PLFLT cosangle = cos( PI * angle / 180. );
00112     PLFLT sinangle = sin( PI * angle / 180. );
00113     affine_vector[0] = cosangle;
00114     affine_vector[1] = -sinangle;
00115     affine_vector[2] = sinangle;
00116     affine_vector[3] = cosangle;
00117     affine_vector[4] = 0.;
00118     affine_vector[5] = 0.;
00119 }
00120 
00121 // Skew new X coordinate axis relative to the old.
00122 // angle is in degrees.
00123 
00124 void
00125 plP_affine_xskew( PLFLT *affine_vector, PLFLT angle )
00126 {
00127     PLFLT tanangle = tan( PI * angle / 180. );
00128     affine_vector[0] = 1.;
00129     affine_vector[1] = 0.;
00130     affine_vector[2] = -tanangle;
00131     affine_vector[3] = 1.;
00132     affine_vector[4] = 0.;
00133     affine_vector[5] = 0.;
00134 }
00135 
00136 // Skew new Y coordinate axis relative to the old.
00137 // angle is in degrees.
00138 
00139 void
00140 plP_affine_yskew( PLFLT *affine_vector, PLFLT angle )
00141 {
00142     PLFLT tanangle = tan( PI * angle / 180. );
00143     affine_vector[0] = 1.;
00144     affine_vector[1] = -tanangle;
00145     affine_vector[2] = 0.;
00146     affine_vector[3] = 1.;
00147     affine_vector[4] = 0.;
00148     affine_vector[5] = 0.;
00149 }
00150 
00151 // Multiply two affine transformation matrices to form a third.
00152 //
00153 // A = B * C
00154 //
00155 //
00156 
00157 void
00158 plP_affine_multiply(
00159     PLFLT *affine_vectorA,
00160     const PLFLT *affine_vectorB,
00161     const PLFLT *affine_vectorC )
00162 {
00163     int   i;
00164     PLFLT result[NAFFINE];
00165     // Multiply two affine matrices stored in affine vector form.
00166     result[0] = affine_vectorB[0] * affine_vectorC[0] +
00167                 affine_vectorB[2] * affine_vectorC[1];
00168     result[2] = affine_vectorB[0] * affine_vectorC[2] +
00169                 affine_vectorB[2] * affine_vectorC[3];
00170     result[4] = affine_vectorB[0] * affine_vectorC[4] +
00171                 affine_vectorB[2] * affine_vectorC[5] +
00172                 affine_vectorB[4];
00173 
00174     result[1] = affine_vectorB[1] * affine_vectorC[0] +
00175                 affine_vectorB[3] * affine_vectorC[1];
00176     result[3] = affine_vectorB[1] * affine_vectorC[2] +
00177                 affine_vectorB[3] * affine_vectorC[3];
00178     result[5] = affine_vectorB[1] * affine_vectorC[4] +
00179                 affine_vectorB[3] * affine_vectorC[5] +
00180                 affine_vectorB[5];
00181 
00182     for ( i = 0; i < NAFFINE; i++ )
00183         affine_vectorA[i] = result[i];
00184 }

Generated on Wed Oct 12 2011 20:42:22 for PLplot by  doxygen 1.7.1