Anti-Grain Geometry - AGG (libagg)
2.5
|
00001 //---------------------------------------------------------------------------- 00002 // Anti-Grain Geometry (AGG) - Version 2.5 00003 // A high quality rendering engine for C++ 00004 // Copyright (C) 2002-2006 Maxim Shemanarev 00005 // Contact: mcseem@antigrain.com 00006 // mcseemagg@yahoo.com 00007 // http://antigrain.com 00008 // 00009 // AGG is free software; you can redistribute it and/or 00010 // modify it under the terms of the GNU General Public License 00011 // as published by the Free Software Foundation; either version 2 00012 // of the License, or (at your option) any later version. 00013 // 00014 // AGG 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 General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU General Public License 00020 // along with AGG; if not, write to the Free Software 00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00022 // MA 02110-1301, USA. 00023 //---------------------------------------------------------------------------- 00024 00025 #ifndef AGG_SIMUL_EQ_INCLUDED 00026 #define AGG_SIMUL_EQ_INCLUDED 00027 00028 #include <math.h> 00029 #include "agg_basics.h" 00030 00031 namespace agg 00032 { 00033 00034 //=============================================================swap_arrays 00035 template<class T> void swap_arrays(T* a1, T* a2, unsigned n) 00036 { 00037 unsigned i; 00038 for(i = 0; i < n; i++) 00039 { 00040 T tmp = *a1; 00041 *a1++ = *a2; 00042 *a2++ = tmp; 00043 } 00044 } 00045 00046 00047 //============================================================matrix_pivot 00048 template<unsigned Rows, unsigned Cols> 00049 struct matrix_pivot 00050 { 00051 static int pivot(double m[Rows][Cols], unsigned row) 00052 { 00053 int k = int(row); 00054 double max_val, tmp; 00055 00056 max_val = -1.0; 00057 unsigned i; 00058 for(i = row; i < Rows; i++) 00059 { 00060 if((tmp = fabs(m[i][row])) > max_val && tmp != 0.0) 00061 { 00062 max_val = tmp; 00063 k = i; 00064 } 00065 } 00066 00067 if(m[k][row] == 0.0) 00068 { 00069 return -1; 00070 } 00071 00072 if(k != int(row)) 00073 { 00074 swap_arrays(m[k], m[row], Cols); 00075 return k; 00076 } 00077 return 0; 00078 } 00079 }; 00080 00081 00082 00083 //===============================================================simul_eq 00084 template<unsigned Size, unsigned RightCols> 00085 struct simul_eq 00086 { 00087 static bool solve(const double left[Size][Size], 00088 const double right[Size][RightCols], 00089 double result[Size][RightCols]) 00090 { 00091 unsigned i, j, k; 00092 double a1; 00093 00094 double tmp[Size][Size + RightCols]; 00095 00096 for(i = 0; i < Size; i++) 00097 { 00098 for(j = 0; j < Size; j++) 00099 { 00100 tmp[i][j] = left[i][j]; 00101 } 00102 for(j = 0; j < RightCols; j++) 00103 { 00104 tmp[i][Size + j] = right[i][j]; 00105 } 00106 } 00107 00108 for(k = 0; k < Size; k++) 00109 { 00110 if(matrix_pivot<Size, Size + RightCols>::pivot(tmp, k) < 0) 00111 { 00112 return false; // Singularity.... 00113 } 00114 00115 a1 = tmp[k][k]; 00116 00117 for(j = k; j < Size + RightCols; j++) 00118 { 00119 tmp[k][j] /= a1; 00120 } 00121 00122 for(i = k + 1; i < Size; i++) 00123 { 00124 a1 = tmp[i][k]; 00125 for (j = k; j < Size + RightCols; j++) 00126 { 00127 tmp[i][j] -= a1 * tmp[k][j]; 00128 } 00129 } 00130 } 00131 00132 00133 for(k = 0; k < RightCols; k++) 00134 { 00135 int m; 00136 for(m = int(Size - 1); m >= 0; m--) 00137 { 00138 result[m][k] = tmp[m][Size + k]; 00139 for(j = m + 1; j < Size; j++) 00140 { 00141 result[m][k] -= tmp[m][j] * result[j][k]; 00142 } 00143 } 00144 } 00145 return true; 00146 } 00147 00148 }; 00149 00150 00151 } 00152 00153 #endif