Changeset 2897 for trunk/stac/src/stacInvertMaps.c
- Timestamp:
- Jan 4, 2005, 3:55:40 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/stac/src/stacInvertMaps.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/stac/src/stacInvertMaps.c
r2500 r2897 5 5 6 6 #define MAX(x,y) ((x) > (y) ? (x) : (y)) 7 8 psArray *stacInvertMaps(const psArray *maps // Array of maps to invert 7 #define NUM_GRID 20 8 9 psArray *stacInvertMaps(const psArray *maps, // Array of maps to invert 10 const stacConfig *config // Configuration 9 11 ) 10 12 { … … 14 16 psTrace("stac.invertMaps", 1, "Inverting maps....\n"); 15 17 16 for (int i = 0; i < nMaps; i++) { 17 // Can't handle higher order than linear yet 18 if (((psPlaneTransform*)maps->data[i])->x->nX != 2 || 19 ((psPlaneTransform*)maps->data[i])->x->nY != 2 || 20 ((psPlaneTransform*)maps->data[i])->y->nX != 2 || 21 ((psPlaneTransform*)maps->data[i])->y->nY != 2) { 22 psError("stac.invertMaps", 23 "STAC cannot currently support orders other than linear.\n"); 24 psFree(inverted); 25 return NULL; 26 } 27 28 psPlaneTransform *newMap = psPlaneTransformAlloc(2, 2); // Inverted map 29 psPlaneTransform *oldMap = (psPlaneTransform*)maps->data[i]; // Uninverted map 30 31 // Now, simply do a 2x2 matrix inversion 32 33 double a = oldMap->x->coeff[1][0]; 34 double b = oldMap->x->coeff[0][1]; 35 double c = oldMap->y->coeff[1][0]; 36 double d = oldMap->y->coeff[0][1]; 37 double e = oldMap->x->coeff[0][0]; 38 double f = oldMap->y->coeff[0][0]; 39 40 double invDet = 1.0 / (a * d - b * c); // Inverse of the determinant 41 42 // Not entirely sure why this works, but it appears to do so....................................... 43 newMap->x->coeff[1][0] = invDet * a; 44 newMap->x->coeff[0][1] = - invDet * b; 45 newMap->y->coeff[1][0] = - invDet * c; 46 newMap->y->coeff[0][1] = invDet * d; 47 48 newMap->x->coeff[0][0] = - invDet * (d * e + c * f); 49 newMap->y->coeff[0][0] = - invDet * (b * e + a * f); 18 // Coordinates for the transformations 19 psPlane *inCoord = psAlloc(sizeof(psPlane)); 20 psPlane *outCoord = psAlloc(sizeof(psPlane)); 21 22 for (int mapNum = 0; mapNum < nMaps; mapNum++) { 23 24 psPlaneTransform *oldMap = (psPlaneTransform*)maps->data[mapNum]; // Uninverted map 25 // Check input 26 if (oldMap->x->nX != oldMap->x->nY) { 27 psError("stac.invertMaps", "Polynomial order in x and y don't match for map %d\n", mapNum); 28 return NULL; 29 } 30 if (oldMap->y->nX != oldMap->y->nY) { 31 psError("stac.invertMaps", "Polynomial order in x and y don't match for map %d\n", mapNum); 32 return NULL; 33 } 34 if (oldMap->x->nX != oldMap->y->nX) { 35 psError("stac.invertMaps", "Polynomial order in x and y don't match for map %d\n", mapNum); 36 return NULL; 37 } 38 int order = oldMap->x->nX; // Polynomial order 39 psTrace("stac.invertMaps", 4, "Generating order %d polynomial inverse transformation.\n", order); 40 psPlaneTransform *newMap = psPlaneTransformAlloc(order, order); // Inverted map 41 42 // Create fake polynomial to use in evaluation 43 psDPolynomial2D *fakePoly = psDPolynomial2DAlloc(order, order, PS_POLYNOMIAL_ORD); 44 for (int i = 0; i < order; i++) { 45 for (int j = 0; j < order; j++) { 46 fakePoly->coeff[i][j] = 1.0; // Set all coeffecients to 1 47 fakePoly->mask[i][j] = 1; // Mask all coefficients; unmask to evaluate 48 } 49 } 50 51 // A grid of xin,yin --> xout,yout 52 psVector *xIn = psVectorAlloc(NUM_GRID * NUM_GRID, PS_TYPE_F32); 53 psVector *yIn = psVectorAlloc(NUM_GRID * NUM_GRID, PS_TYPE_F32); 54 psVector *xOut = psVectorAlloc(NUM_GRID * NUM_GRID, PS_TYPE_F32); 55 psVector *yOut = psVectorAlloc(NUM_GRID * NUM_GRID, PS_TYPE_F32); 56 57 // Create grid of points 58 for (int yint = 0; yint < NUM_GRID; yint++) { 59 inCoord->y = (float)(yint * config->outny) / (float)(NUM_GRID - 1); 60 for (int xint = 0; xint < NUM_GRID; xint++) { 61 inCoord->x = (float)(xint * config->outnx) / (float)(NUM_GRID - 1); 62 63 (void)psPlaneTransformApply(outCoord, oldMap, inCoord); 64 65 xOut->data.F32[yint*NUM_GRID + xint] = inCoord->x; 66 yOut->data.F32[yint*NUM_GRID + xint] = inCoord->y; 67 xIn->data.F32[yint*NUM_GRID + xint] = outCoord->x; 68 yIn->data.F32[yint*NUM_GRID + xint] = outCoord->y; 69 } 70 } 71 72 // Initialise the matrix and vectors 73 int nCoeff = order * (order + 1) / 2; // Number of polynomial coefficients 74 psImage *matrix = psImageAlloc(nCoeff, nCoeff, PS_TYPE_F64); // Matrix for solution 75 psVector *xVector = psVectorAlloc(nCoeff, PS_TYPE_F64); // Vector for solution in x 76 psVector *yVector = psVectorAlloc(nCoeff, PS_TYPE_F64); // Vector for solution in y 77 for (int i = 0; i < nCoeff; i++) { 78 for (int j = 0; j < nCoeff; j++) { 79 matrix->data.F64[i][j] = 0.0; 80 } 81 xVector->data.F64[i] = 0.0; 82 yVector->data.F64[i] = 0.0; 83 } 84 85 // Iterate over the grid points 86 for (int g = 0; g < NUM_GRID*NUM_GRID; g++) { 87 88 // Iterate over the polynomial coefficients, accumulating the matrix and vectors 89 for (int i = 0, ijIndex = 0; i < order; i++) { 90 for (int j = 0; j < order - i; j++, ijIndex++) { 91 92 fakePoly->mask[i][j] = 0; 93 double ijPoly = psDPolynomial2DEval(xIn->data.F32[g], yIn->data.F32[g], fakePoly); 94 fakePoly->mask[i][j] = 1; 95 96 for (int m = 0, mnIndex = 0; m < order; m++) { 97 for (int n = 0; n < order - m; n++, mnIndex++) { 98 99 fakePoly->mask[m][n] = 0; 100 double mnPoly = psDPolynomial2DEval(xIn->data.F32[g], yIn->data.F32[g], fakePoly); 101 fakePoly->mask[m][n] = 1; 102 103 matrix->data.F64[ijIndex][mnIndex] += ijPoly * mnPoly; 104 } 105 } 106 107 xVector->data.F64[ijIndex] += ijPoly * (double)xOut->data.F32[g]; 108 yVector->data.F64[ijIndex] += ijPoly * (double)yOut->data.F32[g]; 109 } 110 } // Iterating over coefficients 111 } // Iterating over grid points 112 113 // Solution via LU Decomposition 114 psVector *permutation = psVectorAlloc(nCoeff, PS_TYPE_F64); // Permutation vector for LU Decomposition 115 psImage *luMatrix = psMatrixLUD(NULL, permutation, matrix); // LU decomposed matrix 116 psVector *xSolution = psMatrixLUSolve(NULL, luMatrix, xVector, permutation); // Solution in x 117 psVector *ySolution = psMatrixLUSolve(NULL, luMatrix, yVector, permutation); // Solution in y 118 119 // Stuff coefficients into transformation 120 for (int i = 0, ijIndex = 0; i < order; i++) { 121 for (int j = 0; j < order - i; j++, ijIndex++) { 122 newMap->x->coeff[i][j] = xSolution->data.F64[ijIndex]; 123 newMap->y->coeff[i][j] = ySolution->data.F64[ijIndex]; 124 } 125 } 126 inverted->data[mapNum] = newMap; 127 128 #ifdef TESTING 129 // Print x coefficients 130 psTrace("stac.invertMaps", 7, "x' = \n"); 131 for (int i = 0; i < order; i++) { 132 for (int j = 0; j < order - i; j++) { 133 psTrace("stac.invertMaps", 7, " %f x^%d y^%d\n", newMap->x->coeff[i][j], i, j); 134 } 135 } 136 // Print y coefficients 137 psTrace("stac.invertMaps", 7, "y' = \n"); 138 for (int i = 0; i < order; i++) { 139 for (int j = 0; j < order - i; j++) { 140 psTrace("stac.invertMaps", 7, " %f x^%d y^%d\n", newMap->y->coeff[i][j], i, j); 141 } 142 } 143 #endif 50 144 51 145 #ifdef TESTING … … 64 158 #endif 65 159 66 inverted->data[i] = newMap; // Stuff into the array 160 psFree(permutation); 161 psFree(luMatrix); 162 psFree(matrix); 163 psFree(xVector); 164 psFree(yVector); 165 psFree(xSolution); 166 psFree(ySolution); 167 psFree(fakePoly); 168 psFree(xIn); 169 psFree(yIn); 170 psFree(xOut); 171 psFree(yOut); 67 172 } 173 174 psFree(inCoord); 175 psFree(outCoord); 176 177 178 #if 0 179 // Can't handle higher order than linear yet 180 if (((psPlaneTransform*)maps->data[i])->x->nX != 2 || 181 ((psPlaneTransform*)maps->data[i])->x->nY != 2 || 182 ((psPlaneTransform*)maps->data[i])->y->nX != 2 || 183 ((psPlaneTransform*)maps->data[i])->y->nY != 2) { 184 psError("stac.invertMaps", 185 "STAC cannot currently support orders other than linear.\n"); 186 psFree(inverted); 187 return NULL; 188 } 189 190 psPlaneTransform *newMap = psPlaneTransformAlloc(2, 2); // Inverted map 191 psPlaneTransform *oldMap = (psPlaneTransform*)maps->data[i]; // Uninverted map 192 193 // Now, simply do a 2x2 matrix inversion 194 195 double a = oldMap->x->coeff[1][0]; 196 double b = oldMap->x->coeff[0][1]; 197 double c = oldMap->y->coeff[1][0]; 198 double d = oldMap->y->coeff[0][1]; 199 double e = oldMap->x->coeff[0][0]; 200 double f = oldMap->y->coeff[0][0]; 201 202 double invDet = 1.0 / (a * d - b * c); // Inverse of the determinant 203 204 // Not entirely sure why this works, but it appears to do so....................................... 205 newMap->x->coeff[1][0] = invDet * a; 206 newMap->x->coeff[0][1] = - invDet * b; 207 newMap->y->coeff[1][0] = - invDet * c; 208 newMap->y->coeff[0][1] = invDet * d; 209 210 newMap->x->coeff[0][0] = - invDet * (d * e + c * f); 211 newMap->y->coeff[0][0] = - invDet * (b * e + a * f); 212 #endif 213 68 214 69 215 return inverted;
Note:
See TracChangeset
for help on using the changeset viewer.
