home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 174.lha / BezSurf / mapcalc.c < prev    next >
C/C++ Source or Header  |  1988-04-28  |  5KB  |  249 lines

  1. #include <math.h>
  2. #include "mytypes.h"
  3. #include "revolve.h"       /* need to get scrnpair from here */
  4. #include "mapstuff.h"
  5. #include "menuexp.h"
  6.  
  7. #ifdef TEST
  8. #undef DebugOn
  9. #define DebugOn 1
  10. #endif TEST
  11.  
  12.  
  13. #define DEBUG
  14. /*
  15.  * this section of code derived from:
  16.  * "The essential algorithms of ray tracing" by Eric Haines
  17.  * presented in Sigraph proceedings on Ray Tracing
  18.  * my major change has been to simplify it for two dimensions
  19.  */
  20.  
  21. typedef struct {
  22.     float x, y;
  23. } Vector;
  24.  
  25. static float DotVector(a,b)
  26.     Vector *a, *b;
  27. {
  28.     return( a->x * b->x + a->y * b->y);
  29. }
  30.  
  31. static void DivVector(in, scale, out)
  32.     Vector *in, *out;
  33.     float scale;
  34. {
  35.     if ( fabs(scale) < SingleTinyVal ) {
  36.         out->x = SingleLargeVal;
  37.         out->y = SingleLargeVal;
  38.     }
  39.     else {
  40.         out->x = in->x / scale;
  41.         out->y = in->y / scale;
  42.     }
  43. }
  44.  
  45.  
  46.  
  47. static Vector Na, Nb, Nc;
  48. static float Du0, Du1, Du2,
  49.              Dv0, Dv1, Dv2;
  50. static Vector Qux, Quy,
  51.               Qvx, Qvy;
  52. static float Dux, Duy,
  53.              Dvx, Dvy;
  54. static bool IsQuadu, IsQuadv;
  55.  
  56. void CalcMapConsts(vp)
  57.     register ScrnPair *vp;
  58. #define p00 vp[0]
  59. #define p01 vp[1]
  60. #define p11 vp[2]
  61. #define p10 vp[3]
  62. {
  63.     Vector Pa, Pb, Pc, Pd;
  64.  
  65.     Pa.x = p00.x - p10.x + p11.x - p01.x;
  66.     Pa.y = p00.y - p10.y + p11.y - p01.y;
  67.  
  68.     Pb.x = p10.x - p00.x;
  69.     Pb.y = p10.y - p00.y;
  70.  
  71.     Pc.x = p01.x - p00.x;
  72.     Pc.y = p01.y - p00.y;
  73.  
  74.     Pd.x = p00.x;
  75.     Pd.y = p00.y;
  76.  
  77.     Na.x = Pa.y; Na.y = -Pa.x;
  78.     Nc.x = Pc.y; Nc.y = -Pc.x;
  79.     Nb.x = Pb.y; Nb.y = -Pb.x;
  80.  
  81.     Du0 = DotVector(&Nc, &Pd);
  82.     Du1 = DotVector(&Na, &Pd) + DotVector(&Nc, &Pb);
  83.     Du2 = DotVector( &Na, &Pb);
  84.  
  85.     if( fabs( Du2 ) > SingleTinyVal ) {
  86.         float TwoDu2;
  87.  
  88.         IsQuadu = true;
  89.         TwoDu2 = 2.0 * Du2;
  90.         DivVector( &Na, TwoDu2, &Qux );
  91.         DivVector( &Nc, -Du2, &Quy );
  92.         Duy = Du0/Du2;
  93.         Dux = -Du1/TwoDu2;
  94.     }
  95.     else {
  96.         IsQuadu = false;
  97.     }
  98.  
  99.     Dv0 = DotVector( &Nb, &Pd);
  100.     Dv1 = DotVector(&Na, &Pd) + DotVector(&Nb, &Pc);
  101.     Dv2 = DotVector( &Na, &Pc);
  102.     if( fabs( Dv2 ) > SingleTinyVal ) {
  103.         float TwoDv2;
  104.  
  105.         IsQuadv = true;
  106.         TwoDv2 = 2.0 * Dv2;
  107.         DivVector( &Na, TwoDv2, &Qvx);
  108.         DivVector( &Nb, -Dv2, &Qvy);
  109. /*      DivVector( &Nc, -Dv2, &Qvy); */
  110.         Dvx = - Dv1/TwoDv2;
  111.         Dvy = Dv0/Dv2;
  112.     }
  113.     else {
  114.         IsQuadv = false;
  115.     }
  116. #ifdef DEBUG
  117.     if( DebugOn ) {
  118.         printf("du2 %f, du1 %f, du0 %f\n", Du2, Du1, Du0 );
  119.         printf("dv2 %f, dv1 %f, dv0 %f\n", Dv2, Dv1, Dv0 );
  120.         printf("Na = (%f, %f), Nb = (%f,%f), Nc = (%f,%f)\n",
  121.         Na.x, Na.y, Nb.x, Nb.y, Nc.x, Nc.y );
  122.         printf("IsQuad =(%c, %c)\n", IsQuadu?'t':'f', IsQuadv? 't': 'f' );
  123.     }
  124. #endif DEBUG
  125.  
  126. }
  127.  
  128.  
  129. /*
  130.  * given points px,py in the quadrilateral, map them to points inside a
  131.  * unit square
  132.  */
  133. void  MapXYRatio(px, py, outx, outy, SweepCode)
  134.     float px, py;
  135.     float *outx, *outy;
  136.     short SweepCode;
  137. {
  138.     float resu, resv;
  139.     Vector Ri;
  140.  
  141.  
  142.     Ri.x = px; Ri.y = py;
  143.  
  144.     if( !IsQuadu ) {
  145.         float denom;
  146.         denom = (Du1 - DotVector(&Na, &Ri));
  147.         if( fabs(denom) < SingleTinyVal )
  148.             resu = 2.0;
  149.         else
  150.             resu = (DotVector(&Nc, &Ri) - Du0)/denom;
  151.     } else {
  152.         float Ka, Kb;
  153.         float discrim;
  154.  
  155.         Ka = Dux + DotVector( &Qux, &Ri);
  156.         Kb = Duy + DotVector( &Quy, &Ri);
  157.         discrim = sqrt(fabs(Ka * Ka - Kb));
  158.         resu = Ka + ((discrim > Ka)? discrim: (-discrim));
  159. #ifdef DEBUG
  160.         if( DebugOn ) {
  161.             printf("dux=%f, duy = %f, ka = %f, kb = %f\n",
  162.                 Dux, Duy, Ka, Kb );
  163.         }
  164. #endif DEBUG
  165.  
  166.     }
  167.  
  168.     if( !IsQuadv ) {
  169.         float denom;
  170.         denom = (Dv1 - DotVector(&Na, &Ri));
  171.         if( fabs(denom) < SingleTinyVal )
  172.             resv = 2.0;
  173.         else
  174.             resv = (DotVector(&Nb, &Ri) - Dv0)/denom;
  175.     } else {
  176.         float Ka, Kb;
  177.         float discrim;
  178.  
  179.         Ka = Dvx + DotVector( &Qvx, &Ri);
  180.         Kb = Dvy + DotVector( &Qvy, &Ri);
  181.         discrim = sqrt(fabs( Ka * Ka - Kb));
  182.         resv = Ka + ((discrim > Ka)? discrim: (-discrim));
  183. #ifdef DEBUG
  184.         if( DebugOn ) {
  185.             printf("dvx=%f, dvy = %f, ka = %f, kb = %f\n",
  186.                 Dvx, Dvy, Ka, Kb );
  187.         }
  188. #endif DEBUG
  189.     }
  190.  
  191. #ifdef DEBUG
  192.     if( DebugOn ) {
  193.         printf("(%f,%f) -> (%f, %f)\n", px, py, resu, resv );
  194.     }
  195. #endif DEBUG
  196.  
  197.     if( resu > 1.0 || resu < 0.0 ) {
  198.         resu = ( SweepCode & MP_XMAX)? 1.0: 0.0;
  199.     }
  200.     if( resv > 1.0 || resv < 0.0 ) {
  201.         resv = ( SweepCode & MP_YMAX)? 1.0: 0.0;
  202.     }
  203.  
  204.     *outx = resu; *outy = resv;
  205. }
  206.  
  207.  
  208.  
  209. /*
  210.  * here abides testcode
  211.  */
  212. #ifdef TEST
  213. #include <stdio.h>
  214.  
  215. ReadScrnPair(set, a)
  216.     char *set;
  217.     ScrnPair *a;
  218. {
  219.     int tx, ty;
  220.     printf("enter screen pair %s\n",set);
  221.     scanf("%d %d", &tx, &ty);
  222.     a->x = tx; a->y = ty;
  223. }
  224.  
  225. ReadLimits(a)
  226. ScrnPair a[];
  227. {
  228.     ReadScrnPair("a", &a[0]);
  229.     ReadScrnPair("b", &a[1]);
  230.     ReadScrnPair("c", &a[2]);
  231.     ReadScrnPair("d", &a[3]);
  232. }
  233.  
  234. main() {
  235.     float inx, iny;
  236.     float outy, outx;
  237.     ScrnPair pts[4];
  238.  
  239.     ReadLimits(pts);
  240.     CalcMapConsts(pts);
  241.     while(!feof(stdin)) {
  242.         printf("enter quadrilateral points\n");
  243.         scanf("%f %f", &inx, &iny );
  244.         MapXYRatio( inx, iny, &outx, &outy, 0);
  245.         printf("p(%f,%f)->p(%f,%f)\n", inx, iny, outx, outy);
  246.     }
  247. }
  248. #endif TEST
  249.