| | 218 | static unsigned long poly_number_terms(double order) |
| | 219 | { |
| | 220 | /* Return the number of terms for a 2d polynomial |
| | 221 | Order must either be an integer, or 1.5 to produce |
| | 222 | the 2 dimentional polyminal function... |
| | 223 | affine 1 (3) u = c0 + c1*x + c2*y |
| | 224 | bilinear 1.5 (4) u = '' + c3*x*y |
| | 225 | quadratic 2 (6) u = '' + c4*x*x + c5*y*y |
| | 226 | cubic 3 (10) u = '' + c6*x^3 + c7*x*x*y + c8*x*y*y + c9*y^3 |
| | 227 | quartic 4 (15) u = '' + c10*x^4 + ... + c14*y^4 |
| | 228 | quintic 5 (21) u = '' + c15*x^5 + ... + c20*y^5 |
| | 229 | number in parenthesis is minimum number of points needed. |
| | 230 | Anything beyond quintic, has not been implemented until |
| | 231 | a more automated way of determined terms is found. |
| | 232 | */ |
| | 233 | if ( order < 1 || order > 5 || |
| | 234 | ( order != floor(order) && (order-1.5) > MagickEpsilon) ) |
| | 235 | return 0; /* invalid polynomial order */ |
| | 236 | return ( (long)floor((order+1)*(order+2)/2) ); |
| | 237 | } |
| | 238 | |
| | 239 | static double poly_term(long n, double x, double y) |
| | 240 | { |
| | 241 | /* return the result for this polynomial term */ |
| | 242 | switch(n) { |
| | 243 | case 0: return( 1.0 ); /* constant */ |
| | 244 | case 1: return( x ); |
| | 245 | case 2: return( y ); /* affine order = 1 terms = 3 */ |
| | 246 | case 3: return( x*y ); /* bilinear order = 1.5 terms = 4 */ |
| | 247 | case 4: return( x*x ); |
| | 248 | case 5: return( y*y ); /* quadratic order = 2 terms = 6 */ |
| | 249 | case 6: return( x*x*x ); |
| | 250 | case 7: return( x*x*y ); |
| | 251 | case 8: return( x*y*y ); |
| | 252 | case 9: return( y*y*y ); /* cubic order = 3 terms = 10 */ |
| | 253 | case 10: return( x*x*x*x ); |
| | 254 | case 11: return( x*x*x*y ); |
| | 255 | case 12: return( x*x*y*y ); |
| | 256 | case 13: return( x*y*y*y ); |
| | 257 | case 14: return( y*y*y*y ); /* quartic order = 4 terms = 15 */ |
| | 258 | case 15: return( x*x*x*x*x ); |
| | 259 | case 16: return( x*x*x*x*y ); |
| | 260 | case 17: return( x*x*x*y*y ); |
| | 261 | case 18: return( x*x*y*y*y ); |
| | 262 | case 19: return( x*y*y*y*y ); |
| | 263 | case 20: return( y*y*y*y*y ); /* quintic order = 5 terms = 21 */ |
| | 264 | } |
| | 265 | return( 0 ); /* should never happen */ |
| | 266 | } |
| | 267 | static const char *poly_term_str(long n) |
| | 268 | { |
| | 269 | /* return the result for this polynomial term */ |
| | 270 | switch(n) { |
| | 271 | case 0: return(""); /* constant */ |
| | 272 | case 1: return("*xx"); |
| | 273 | case 2: return("*yy"); /* affine order = 1 terms = 3 */ |
| | 274 | case 3: return("*xx*yy"); /* bilinear order = 1.5 terms = 4 */ |
| | 275 | case 4: return("*xx*xx"); |
| | 276 | case 5: return("*yy*yy"); /* quadratic order = 2 terms = 6 */ |
| | 277 | case 6: return("*xx*xx*xx"); |
| | 278 | case 7: return("*xx*xx*yy"); |
| | 279 | case 8: return("*xx*yy*yy"); |
| | 280 | case 9: return("*yy*yy*yy"); /* cubic order = 3 terms = 10 */ |
| | 281 | case 10: return("*xx*xx*xx*xx"); |
| | 282 | case 11: return("*xx*xx*xx*yy"); |
| | 283 | case 12: return("*xx*xx*yy*yy"); |
| | 284 | case 13: return("*xx*yy*yy*yy"); |
| | 285 | case 14: return("*yy*yy*yy*yy"); /* quartic order = 4 terms = 15 */ |
| | 286 | case 15: return("*xx*xx*xx*xx*xx"); |
| | 287 | case 16: return("*xx*xx*xx*xx*yy"); |
| | 288 | case 17: return("*xx*xx*xx*yy*yy"); |
| | 289 | case 18: return("*xx*xx*yy*yy*yy"); |
| | 290 | case 19: return("*xx*yy*yy*yy*yy"); |
| | 291 | case 20: return("*yy*yy*yy*yy*yy"); /* quintic order = 5 terms = 21 */ |
| | 292 | } |
| | 293 | return( "UNKNOWN" ); /* should never happen */ |
| | 294 | } |
| | 295 | static double poly_term_dx(long n, double x, double y) |
| | 296 | { |
| | 297 | /* polynomial term for x derivative */ |
| | 298 | switch(n) { |
| | 299 | case 0: return( 0.0 ); /* constant */ |
| | 300 | case 1: return( 1.0 ); |
| | 301 | case 2: return( 0.0 ); /* affine order = 1 terms = 3 */ |
| | 302 | case 3: return( y ); /* bilinear order = 1.5 terms = 4 */ |
| | 303 | case 4: return( x ); |
| | 304 | case 5: return( 0.0 ); /* quadratic order = 2 terms = 6 */ |
| | 305 | case 6: return( x*x ); |
| | 306 | case 7: return( x*y ); |
| | 307 | case 8: return( y*y ); |
| | 308 | case 9: return( 0.0 ); /* cubic order = 3 terms = 10 */ |
| | 309 | case 10: return( x*x*x ); |
| | 310 | case 11: return( x*x*y ); |
| | 311 | case 12: return( x*y*y ); |
| | 312 | case 13: return( y*y*y ); |
| | 313 | case 14: return( 0.0 ); /* quartic order = 4 terms = 15 */ |
| | 314 | case 15: return( x*x*x*x ); |
| | 315 | case 16: return( x*x*x*y ); |
| | 316 | case 17: return( x*x*y*y ); |
| | 317 | case 18: return( x*y*y*y ); |
| | 318 | case 19: return( y*y*y*y ); |
| | 319 | case 20: return( 0.0 ); /* quintic order = 5 terms = 21 */ |
| | 320 | } |
| | 321 | return( 0.0 ); /* should never happen */ |
| | 322 | } |
| | 323 | static double poly_term_dy(long n, double x, double y) |
| | 324 | { |
| | 325 | /* polynomial term for y derivative */ |
| | 326 | switch(n) { |
| | 327 | case 0: return( 0.0 ); /* constant */ |
| | 328 | case 1: return( 0.0 ); |
| | 329 | case 2: return( 1.0 ); /* affine order = 1 terms = 3 */ |
| | 330 | case 3: return( x ); /* bilinear order = 1.5 terms = 4 */ |
| | 331 | case 4: return( 0.0 ); |
| | 332 | case 5: return( y ); /* quadratic order = 2 terms = 6 */ |
| | 333 | default: return( poly_term_dx(n-1,x,y) ); /* weird but true */ |
| | 334 | } |
| | 335 | /* NOTE: the only reason that last is not true for 'quadtratic' |
| | 336 | is due to the re-arrangement of terms to allow for 'bilinear' |
| | 337 | */ |
| | 338 | } |
| | 377 | case ScaleRotateTranslateDistortion: |
| | 378 | case AffineDistortion: |
| | 379 | case AffineProjectionDistortion: |
| | 380 | number_coefficients=6; |
| | 381 | break; |
| | 382 | case PerspectiveDistortion: |
| | 383 | case PerspectiveProjectionDistortion: |
| | 384 | number_coefficients=9; |
| | 385 | break; |
| | 386 | case BilinearDistortion: |
| | 387 | number_coefficients=8; |
| | 388 | break; |
| | 389 | case PolynomialDistortion: |
| | 390 | if ( number_arguments < 5 && (number_arguments-1)%4 != 0) |
| | 391 | { |
| | 392 | (void) ThrowMagickException(exception,GetMagickModule(),OptionError, |
| | 393 | "InvalidArgument","%s : '%s'","distort Polynomial", |
| | 394 | "Invalid number of coord-pairs: order [sX,sY,dX,dY]*"); |
| | 395 | return((double *) NULL); |
| | 396 | } |
| | 397 | number_coefficients = poly_number_terms(arguments[0]); |
| | 398 | if ( number_coefficients == 0 ) |
| | 399 | { |
| | 400 | (void) ThrowMagickException(exception,GetMagickModule(),OptionError, |
| | 401 | "InvalidArgument","%s : '%s'","distort Polynomial", |
| | 402 | "Invalid order, should be 1,1.5,2,3,4 or 5"); |
| | 403 | return((double *) NULL); |
| | 404 | } |
| | 405 | if ( number_arguments < number_coefficients*4+1) |
| | 406 | { |
| | 407 | (void) ThrowMagickException(exception,GetMagickModule(),OptionError, |
| | 408 | "InvalidArgument", "%s : '%s %ld'","distort Polynomial", |
| | 409 | "Not enough coord-pairs, minimum", number_coefficients); |
| | 410 | return((double *) NULL); |
| | 411 | } |
| | 412 | number_coefficients = number_coefficients*2+1; |
| | 413 | break; |
| | 414 | case ArcDistortion: |
| | 415 | number_coefficients=5; |
| | 416 | break; |
| | 417 | case UndefinedDistortion: |
| | 418 | default: |
| | 419 | number_coefficients=0; /* should never happen */ |
| | 420 | break; |
| | 421 | } |
| | 422 | |
| | 423 | /* allocate the array of coefficients needed */ |
| | 424 | coefficients = AcquireQuantumMemory(number_coefficients, |
| | 425 | sizeof(*coefficients)); |
| | 426 | if (coefficients == (double *) NULL) { |
| | 427 | (void) ThrowMagickException(exception,GetMagickModule(), |
| | 428 | ResourceLimitError,"MemoryAllocationFailed", |
| | 429 | "%s", "DistortCoefficients"); |
| | 430 | return((double *) NULL); |
| | 431 | } |
| | 432 | /* zero out coeffiecents array */ |
| | 433 | for (i=0; i < (long)number_coefficients; i++) |
| | 434 | coefficients[i] = 0.0; |
| | 435 | |
| | 436 | switch (*method) |
| | 437 | { |
| 375 | | fprintf(stderr, "Affine ReverseMap\n"); |
| 376 | | for (i=0; i<6; i++) |
| 377 | | fprintf(stderr, " %lf\n", coefficients[i]); |
| 378 | | fprintf(stderr, "Affine Projection\n"); |
| 379 | | for (i=0; i<6; i++) |
| 380 | | fprintf(stderr, " %lf\n", inverse[i]); |
| | 561 | fprintf(stderr, "Affine Reverse Map\n"); |
| | 562 | fprintf(stderr, " -fx 'xx=%+lf*i %+lf*j %+lf;\n", |
| | 563 | coefficients[0], coefficients[2], coefficients[4]); |
| | 564 | fprintf(stderr, " yy=%+lf*i %+lf*j %+lf; p{xx,yy}'\n", |
| | 565 | coefficients[1], coefficients[3], coefficients[5]); |
| | 566 | fprintf(stderr, "Affine Forward Map\n"); |
| | 567 | fprintf(stderr, " -distort AffineProjection \\\n '"); |
| | 568 | for (i=0; i<5; i++) |
| | 569 | fprintf(stderr, "%lg,", inverse[i]); |
| | 570 | fprintf(stderr, "%lg'\n", inverse[5]); |
| 501 | | fprintf(stderr, "Perspective ReverseMap\n"); |
| 502 | | for (i=0; i<8; i++) |
| 503 | | fprintf(stderr, " %lf\n", coefficients[i]); |
| 504 | | fprintf(stderr, "PerspectiveProjection\n"); |
| 505 | | for (i=0; i<8; i++) |
| 506 | | fprintf(stderr, " %lf\n", inverse[i]); |
| | 694 | fprintf(stderr, "Perspective Reverse Map\n"); |
| | 695 | fprintf(stderr, " -fx 'xx=%+lf*i %+lf*j %+lf;\n", |
| | 696 | coefficients[0], coefficients[1], coefficients[2]); |
| | 697 | fprintf(stderr, " yy=%+lf*i %+lf*j %+lf;\n", |
| | 698 | coefficients[3], coefficients[4], coefficients[5]); |
| | 699 | fprintf(stderr, " rr=%+lf*i %+lf*j + 1; p{xx/rr,yy/rr}'\n", |
| | 700 | coefficients[6], coefficients[7]); |
| | 701 | fprintf(stderr, "Perspective Forward Map\n"); |
| | 702 | fprintf(stderr, " -distort PerspectiveProjection \\\n '"); |
| | 703 | for (i=0; i<4; i++) |
| | 704 | fprintf(stderr, "%lg,", inverse[i]); |
| | 705 | fprintf(stderr, "\n "); |
| | 706 | for (; i<7; i++) |
| | 707 | fprintf(stderr, "%lg,", inverse[i]); |
| | 708 | fprintf(stderr, "%lg'\n", inverse[7]); |
| 524 | | fprintf(stderr, "Perspective ReverseMap\n"); |
| 525 | | for (i=0; i<8; i++) |
| 526 | | fprintf(stderr, " %lf\n", coefficients[i]); |
| 527 | | fprintf(stderr, "PerspectiveProjection\n"); |
| 528 | | for (i=0; i<8; i++) |
| 529 | | fprintf(stderr, " %lf\n", arguments[i]); |
| | 726 | fprintf(stderr, "Perspective Reverse Map\n"); |
| | 727 | fprintf(stderr, " -fx 'xx=%+lf*i %+lf*j %+lf;\n", |
| | 728 | coefficients[0], coefficients[1], coefficients[2]); |
| | 729 | fprintf(stderr, " yy=%+lf*i %+lf*j %+lf;\n", |
| | 730 | coefficients[3], coefficients[4], coefficients[5]); |
| | 731 | fprintf(stderr, " rr=%+lf*i %+lf*j + 1; p{xx/rr,yy/rr}'\n", |
| | 732 | coefficients[6], coefficients[7]); |
| | 800 | if ( GetImageArtifact(image,"distort:verbose") != (const char *) NULL ) { |
| | 801 | fprintf(stderr, "Bilinear Reverse Map\n"); |
| | 802 | fprintf(stderr, " -fx 'xx=%+lf*i %+lf*j %+lf*i*j %+lf;\n", |
| | 803 | coefficients[0], coefficients[1], coefficients[2], coefficients[3]); |
| | 804 | fprintf(stderr, " yy=%+lf*i %+lf*j %+lf*i*j %+lf;\n", |
| | 805 | coefficients[4], coefficients[5], coefficients[6], coefficients[7]); |
| | 806 | fprintf(stderr, " p{xx,yy}'\n"); |
| | 807 | } |
| | 808 | return(coefficients); |
| | 809 | } |
| | 810 | case PolynomialDistortion: |
| | 811 | { |
| | 812 | /* Polynomial Distortion |
| | 813 | c0 = number of terms in one polynomial equation |
| | 814 | |
| | 815 | u = c1 + c1*x + c2*y + c3*x*y + ... + c8*x^3 + c9*y^3 |
| | 816 | v = .... |
| | 817 | |
| | 818 | Input Arguments are pairs of distorted coodinates |
| | 819 | Which will be used to generate the coefficients of the above. |
| | 820 | u1,v1, x1,y1, u2,v2, x2,y2, u3,v3, x3,y3, u4,v4, x4,y4 ... |
| | 821 | */ |
| | 822 | double |
| | 823 | **matrix, |
| | 824 | *vectors[2], |
| | 825 | *terms; |
| | 826 | |
| | 827 | long |
| | 828 | nterms; |
| | 829 | |
| | 830 | register long |
| | 831 | j; |
| | 832 | |
| | 833 | MagickBooleanType |
| | 834 | status; |
| | 835 | |
| | 836 | nterms = coefficients[0] = poly_number_terms(arguments[0]); |
| | 837 | |
| | 838 | terms = AcquireQuantumMemory(nterms, sizeof(*terms)); |
| | 839 | if (terms == (double *) NULL) { |
| | 840 | coefficients = RelinquishMagickMemory(coefficients); |
| | 841 | (void) ThrowMagickException(exception,GetMagickModule(), |
| | 842 | ResourceLimitError,"MemoryAllocationFailed", |
| | 843 | "%s", "DistortCoefficients"); |
| | 844 | return((double *) NULL); |
| | 845 | } |
| | 846 | matrix = AcquireMagickMatrix(nterms,nterms); |
| | 847 | if (matrix == (double **) NULL) { |
| | 848 | terms = RelinquishMagickMemory(terms); |
| | 849 | coefficients = RelinquishMagickMemory(coefficients); |
| | 850 | (void) ThrowMagickException(exception,GetMagickModule(), |
| | 851 | ResourceLimitError,"MemoryAllocationFailed", |
| | 852 | "%s", "DistortCoefficients"); |
| | 853 | return((double *) NULL); |
| | 854 | } |
| | 855 | /* fake a 2xN vectors matrix from rest of coefficients array */ |
| | 856 | vectors[0] = &(coefficients[1]); |
| | 857 | vectors[1] = &(coefficients[nterms+1]); |
| | 858 | /* Add control points for least squares solving */ |
| | 859 | for (i=2; i < (long) number_arguments; i+=4) { |
| | 860 | for (j=0; j < nterms; j++) |
| | 861 | terms[j] = poly_term(j,arguments[i],arguments[i+1]); |
| | 862 | LeastSquaresAddTerms(matrix,vectors,terms,&(arguments[i]),nterms,2UL); |
| | 863 | } |
| | 864 | terms = RelinquishMagickMemory(terms); |
| | 865 | /* Solve for LeastSquares Coefficients */ |
| | 866 | status=GaussJordanElimination(matrix,vectors,nterms,2UL); |
| | 867 | matrix = RelinquishMagickMatrix(matrix, nterms); |
| | 868 | if ( status == MagickFalse ) { |
| | 869 | coefficients = RelinquishMagickMemory(coefficients); |
| | 870 | (void) ThrowMagickException(exception,GetMagickModule(),OptionError, |
| | 871 | "InvalidArgument","%s : '%s'","distort Polynomial", |
| | 872 | "Unsolvable Matrix"); |
| | 873 | return((double *) NULL); |
| | 874 | } |
| | 875 | if ( GetImageArtifact(image,"distort:verbose") != (const char *) NULL ) { |
| | 876 | fprintf(stderr, "Polynomial (%ld terms) Reverse Map\n", (long)nterms); |
| | 877 | fprintf(stderr, " -fx 'xx="); |
| | 878 | for (i=0; i<nterms; i++) { |
| | 879 | if ( i != 0 && i%3 == 0 ) fprintf(stderr, "\n "); |
| | 880 | fprintf(stderr, " %lf%s", coefficients[i+1], poly_term_str(i)); |
| | 881 | } |
| | 882 | fprintf(stderr, "\n yy="); |
| | 883 | for (i=0; i<nterms; i++) { |
| | 884 | if ( i != 0 && i%3 == 0 ) fprintf(stderr, "\n "); |
| | 885 | fprintf(stderr, " %lf%s", coefficients[i+1+nterms], poly_term_str(i)); |
| | 886 | } |
| | 887 | fprintf(stderr, "\n p{xx,yy}'\n"); |
| | 888 | } |
| | 1009 | if ( GetImageArtifact(image,"distort:verbose") != (const char *) NULL ) { |
| | 1010 | double *inverse = AcquireQuantumMemory(8,sizeof(coefficients[i])); |
| | 1011 | if (inverse == (double *) NULL) { |
| | 1012 | coefficients = RelinquishMagickMemory(coefficients); |
| | 1013 | (void) ThrowMagickException(exception,GetMagickModule(), |
| | 1014 | ResourceLimitError,"MemoryAllocationFailed", |
| | 1015 | "%s", "DistortCoefficients"); |
| | 1016 | return((double *) NULL); |
| | 1017 | } |
| | 1018 | InvertAffineCoefficients(coefficients, inverse); |
| | 1019 | fprintf(stderr, "Affine Reverse Map\n"); |
| | 1020 | fprintf(stderr, " -fx 'xx=%+lf*i %+lf*j %+lf;\n", |
| | 1021 | coefficients[0], coefficients[2], coefficients[4]); |
| | 1022 | fprintf(stderr, " yy=%+lf*i %+lf*j %+lf; p{xx,yy}'\n", |
| | 1023 | coefficients[1], coefficients[3], coefficients[5]); |
| | 1024 | fprintf(stderr, "Affine Forward Map\n"); |
| | 1025 | fprintf(stderr, " -distort AffineProjection \\\n '"); |
| | 1026 | for (i=0; i<5; i++) |
| | 1027 | fprintf(stderr, "%lg,", inverse[i]); |
| | 1028 | fprintf(stderr, "%lg'\n", inverse[5]); |
| | 1029 | inverse = RelinquishMagickMemory(inverse); |
| | 1030 | } |
| | 1097 | if ( GetImageArtifact(image,"distort:verbose") != (const char *) NULL ) { |
| | 1098 | fprintf(stderr, "Arc Reverse Map\n"); |
| | 1099 | #if 0 |
| | 1100 | Not working yet |
| | 1101 | fprintf(stderr, "c0=%-8lg # angle for center line in source image\n", |
| | 1102 | coefficients[0]); |
| | 1103 | fprintf(stderr, "c1=%-8lg # angle scale for mapping to source image\n", |
| | 1104 | coefficients[1]); |
| | 1105 | fprintf(stderr, "c2=%-8lg # radius for top of source imagen\n", |
| | 1106 | coefficients[2]); |
| | 1107 | fprintf(stderr, "c3=%-8lg # radius scale for mapping source image\n", |
| | 1108 | coefficients[3]); |
| | 1109 | fprintf(stderr, "c4=%-8lg # centerline of arc within source image\n", |
| | 1110 | coefficients[4]); |
| | 1111 | |
| | 1112 | coefficients[1] = 2.0*MagickPI*image->columns/coefficients[1]; |
| | 1113 | coefficients[3] = 1.0*image->rows/coefficients[3]; |
| | 1114 | point.x = (atan2((double)y,(double)x) - coefficients[0])/(2*MagickPI); |
| | 1115 | point.x -= MagickRound(point.x); /* angle */ |
| | 1116 | point.y = sqrt((double) x*x+y*y); /* radius */ |
| | 1117 | point.x = point.x*coefficients[1] + coefficients[4]; |
| | 1118 | point.y = (coefficients[2] - point.y) * coefficients[3]; |
| | 1119 | |
| | 1120 | |
| | 1121 | fprintf(stderr, " -size %ldx%ld -page -%ld-%ld xc: +swap \\\n", |
| | 1122 | (long)coefficients[2]*2+2, (long)coefficients[2]*2+2, |
| | 1123 | (long)coefficients[2]+1, (long)coefficients[2]+1); |
| | 1124 | fprintf(stderr, " -fx 'xx=(atan2(j-h/2,i-w/2) %+lg)*2*pi;\n", |
| | 1125 | coefficients[0]); |
| | 1126 | fprintf(stderr, " xx=(xx%%1+1.5)%%1-0.5;\n"); |
| | 1127 | fprintf(stderr, " yy=hypot(i-w/2,j-h/2);\n"); |
| | 1128 | fprintf(stderr, " xx=xx*%lg + %lg;\n", |
| | 1129 | 2.0*MagickPI*image->columns/coefficients[1], coefficients[4]); |
| | 1130 | fprintf(stderr, " yy=(%lg - yy) * %lg;\n", |
| | 1131 | coefficients[2], ((double)image->rows)/coefficients[3] ); |
| | 1132 | fprintf(stderr, " v.p{xx,yy}'\n"); |
| | 1133 | #endif |
| | 1134 | } |
| | 1493 | case BilinearDistortion: |
| | 1494 | { |
| | 1495 | point.x=coefficients[0]*x+coefficients[1]*y+coefficients[2]*x*y+ |
| | 1496 | coefficients[3]; |
| | 1497 | point.y=coefficients[4]*x+coefficients[5]*y+coefficients[6]*x*y+ |
| | 1498 | coefficients[7]; |
| | 1499 | /* Bilinear partial derivitives of scaling vectors */ |
| | 1500 | ScaleResampleFilter( resample_filter[id], |
| | 1501 | coefficients[0] + coefficients[2]*y, |
| | 1502 | coefficients[1] + coefficients[2]*x, |
| | 1503 | coefficients[4] + coefficients[6]*y, |
| | 1504 | coefficients[5] + coefficients[6]*x ); |
| | 1505 | break; |
| | 1506 | } |
| | 1507 | case PolynomialDistortion: |
| | 1508 | { |
| | 1509 | register long |
| | 1510 | k; |
| | 1511 | |
| | 1512 | double |
| | 1513 | dudx,dudy,dvdx,dvdy; |
| | 1514 | |
| | 1515 | point.x=point.y=dudx=dudy=dvdx=dvdy=0.0; |
| | 1516 | for(k=0; k < coefficients[0]; k++) { |
| | 1517 | point.x += poly_term(k,x,y)*coefficients[k+1]; |
| | 1518 | dudx += poly_term_dx(k,x,y)*coefficients[k+1]; |
| | 1519 | dudy += poly_term_dy(k,x,y)*coefficients[k+1]; |
| | 1520 | point.y += poly_term(k,x,y)*coefficients[k+1+(long)coefficients[0]]; |
| | 1521 | dvdx += poly_term_dx(k,x,y)*coefficients[k+1+(long)coefficients[0]]; |
| | 1522 | dvdy += poly_term_dy(k,x,y)*coefficients[k+1+(long)coefficients[0]]; |
| | 1523 | } |
| | 1524 | ScaleResampleFilter( resample_filter[id], dudx,dudy,dvdx,dvdy ); |
| | 1525 | break; |
| | 1526 | } |