home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / graphic / qrt / msc_patt.c < prev    next >
C/C++ Source or Header  |  1990-01-29  |  6KB  |  232 lines

  1. /**********************************************************
  2.  
  3.                 Pattern and texture module
  4.  
  5.  **********************************************************/
  6.  
  7. #include "qrt.h"
  8. #include "pattern.h"
  9.  
  10.  /* #define PATTERNDEBUG 1 */
  11.  
  12.  
  13. /**********************************************************
  14.  
  15.     Given two coordinates on the surface of an object,
  16.     and a pointer to a colorinfo structure, this routine
  17.     fills the structure with the objects color info at
  18.     this location. If the object does not have an associated
  19.     pattern, its default colorinfo is returned.  The
  20.     routine returns TRUE if the pattern is hit, FALSE
  21.     otherwise.
  22.  
  23.  **********************************************************/
  24.  
  25. int Find_Color(obj, pattern, loc, cinfo, xmult, ymult)
  26.   OBJ_PTR     obj;
  27.   PATTERN_PTR pattern;
  28.   VECT_PTR    loc;
  29.   CINFO_PTR   cinfo;
  30.   float       xmult, ymult;
  31.  
  32. {
  33.   int           temp;         /* added to get around MSC 5.1 bug */
  34.   PATTERN_PTR   patt;
  35.   float         modpos1, modpos2, pos1, pos2;
  36.   int           modx, mody;
  37.  
  38.  
  39.   if (pattern==NULL) {                      /* no pattern */
  40.     copy_colorinfo(cinfo,&(obj->cinfo));
  41.     return(FALSE);
  42.   }
  43.  
  44. # ifdef ROBUST
  45.     if (pattern->type != PATT_HEADER)
  46.       Error(INTERNAL_ERROR,1001);
  47.  
  48.     if ((xmult==0) || (ymult==0))
  49.       Error(ZERO_MULTIPLIER,1002);
  50. # endif
  51.  
  52.   /* find object relative position */
  53.  
  54.   (*(ObjData[obj->type].RelPos))(obj,loc,&pos1,&pos2,FALSE);
  55.  
  56.   pos1 /= xmult;                            /* x and y multipliers */
  57.   pos2 /= ymult;                            /* for pattern sizing  */
  58.  
  59.   modx = (int)(pos1 / (pattern->xsize));
  60.   if (pos1<0) modx--;
  61.  
  62.   mody = (int)(pos2 / (pattern->ysize));
  63.   if (pos2<0) mody--;
  64.  
  65.   modpos1 = pos1 - ((float)modx * pattern->xsize);
  66.   modpos2 = pos2 - ((float)mody * pattern->ysize);
  67.  
  68. # ifdef PATTERNDEBUG
  69.     printf("FINDCOLOR: modpos1,2 = %f %f\n",modpos1, modpos2);
  70.     printf("           mod x,y   = %d %d\n",modx, mody);
  71.     printf("           mult1,2   = %f %f\n",xmult,ymult);
  72. # endif
  73.  
  74.   patt = pattern->child;
  75.  
  76.   while (patt!=NULL) {
  77.  
  78.     THEWORLD.pattern_matches++;
  79.  
  80.     temp = (*(PattData[patt->type].PattHit))(modpos1, modpos2, patt);
  81.     if (temp) {
  82.       copy_colorinfo(cinfo,&(patt->cinfo));
  83.       return(TRUE);
  84.     }
  85.  
  86.     patt = patt->sibling;
  87.   }
  88.  
  89.   copy_colorinfo(cinfo,&(obj->cinfo));
  90.   return(FALSE);
  91. }
  92.  
  93.  
  94. /**********************************************************
  95.  
  96.          Determines if point is inside rectangle
  97.  
  98.  **********************************************************/
  99.  
  100. int Rect_Hit(pos1, pos2, patt)
  101.   float pos1, pos2;
  102.   PATTERN_PTR patt;
  103. {
  104.  
  105. # ifdef PATTERNDEBUG
  106.   printf("RECT_HIT: sx,y = %f %f\n",patt->startx,patt->starty);
  107.   printf("          ex,y = %f %f\n",patt->endx,patt->endy);
  108. # endif
  109.  
  110. # ifdef ROBUST
  111.     if (patt->type != RECT_PATTERN)
  112.       Error(INTERNAL_ERROR,1003);
  113. # endif
  114.  
  115.   if ( (pos1 > patt->startx) &&
  116.        (pos1 < patt->endx)   &&
  117.        (pos2 > patt->starty) &&
  118.        (pos2 < patt->endy) )      return(TRUE);
  119.  
  120.   return(FALSE);
  121. }
  122.  
  123.  
  124. /**********************************************************
  125.  
  126.          Determines if point is inside circle
  127.  
  128.  **********************************************************/
  129.  
  130. int Circle_Hit(pos1, pos2, patt)
  131.   float pos1, pos2;
  132.   PATTERN_PTR patt;
  133. {
  134.   float rad, a, b;
  135.  
  136. # ifdef ROBUST
  137.     if (patt->type != CIRCLE_PATTERN)
  138.       Error(INTERNAL_ERROR,1004);
  139. # endif
  140.  
  141.   a = (pos1 - patt->radius);      /* bug in damn compiler  */
  142.   b = (pos2 - patt->radius);      /* we have to break up   */
  143.                                   /* long float operations */
  144.   rad = sqr(a)+sqr(b);
  145.  
  146. # ifdef PATTERNDEBUG
  147.     printf("CIRC_HIT\n");
  148.     printf("  p1, p2 = %f %f\n",pos1,pos2);
  149.     printf("  rad    = %f\n",patt->radius);
  150.     printf(" crad    = %f\n",rad);
  151. # endif
  152.  
  153.   if (rad <= sqr(patt->radius)) return(TRUE);
  154.  
  155.   return(FALSE);
  156. }
  157.  
  158.  
  159. /**********************************************************
  160.  
  161.    Determines if point px, py intersects line x1,y1,x2,y2.
  162.    Returns true if it does.
  163.  
  164.  **********************************************************/
  165.  
  166. int line_intersect(px, py, x1, y1, x2, y2)
  167.   float px, py, x1, y1, x2, y2;
  168. {
  169.   float t;
  170.  
  171.   x1 -= px; x2 -= px;           /* translate line */
  172.   y1 -= py; y2 -= py;
  173.  
  174.   if ((y1 > 0.0) && (y2 > 0.0)) return(FALSE);
  175.   if ((y1 < 0.0) && (y2 < 0.0)) return(FALSE);
  176.   if ((x1 < 0.0) && (x2 < 0.0)) return(FALSE);
  177.  
  178.   if (y1 == y2) {
  179.     if (y1 != 0.0) return(FALSE);
  180.     if ((x1 > 0.0) || (x2 > 0.0)) return(FALSE);
  181.     return(TRUE);
  182.   }
  183.  
  184.   t = (-y1) / (y2 - y1);
  185.  
  186.   if ((x1 + t * (x2 - x1)) > 0.0) return(TRUE);
  187.   return(FALSE);
  188. }
  189.  
  190. /**********************************************************
  191.  
  192.          Determines if point is inside Polygon
  193.  
  194.  **********************************************************/
  195.  
  196. int Poly_Hit(pos1, pos2, patt)
  197.   float pos1, pos2;
  198.   PATTERN_PTR patt;
  199. {
  200.   float xpos, ypos, nxpos, nypos;
  201.   PATTERN_PTR lseg;
  202.   int count;
  203.  
  204. # ifdef ROBUST
  205.     if (patt->type != POLY_PATTERN)
  206.       Error(INTERNAL_ERROR,1005);
  207. # endif
  208.  
  209.   lseg = patt->link;
  210.  
  211.   if (lseg == NULL) Error(INTERNAL_ERROR,1006);
  212.  
  213.   count = 0;
  214.  
  215.   while (lseg->link != NULL) {
  216.  
  217.      if (line_intersect( pos1, pos2,
  218.                          lseg->startx, lseg->starty,
  219.                          lseg->link->startx,
  220.                          lseg->link->starty) )
  221.        count++;
  222.  
  223.      lseg = lseg->link;
  224.   }
  225.  
  226.   if ((count % 2) == 0) return(FALSE);
  227.   return(TRUE);
  228. }
  229.  
  230.  
  231.  
  232.