home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1980 < prev    next >
Encoding:
Internet Message Format  |  1990-12-28  |  4.6 KB

  1. From: corkum@csri.toronto.edu (Brent Thomas Corkum)
  2. Newsgroups: alt.sources
  3. Subject: [graphics] clockwise or counter-clockwise 2d polygons
  4. Message-ID: <1990Oct22.200250.16671@math.lsa.umich.edu>
  5. Date: 22 Oct 90 20:02:50 GMT
  6.  
  7. Archive-name: clockwise-polygon/22-Oct-90
  8. Original-posting-by: corkum@csri.toronto.edu (Brent Thomas Corkum)
  9. Original-subject: clockwise or counter-clockwise 2d polygons
  10. Reposted-by: emv@math.lsa.umich.edu (Edward Vielmetti)
  11.  
  12. [Reposted from comp.graphics.
  13. Comments on this service to emv@math.lsa.umich.edu (Edward Vielmetti).]
  14.  
  15. This routine and sample program computes whether a 2D polygon is clockwise
  16. or counter-clockwise. The function takes vertices passed in an array
  17. (x1,y1,x2,y2,...xn,yn where n=#vertices) and the number of vertices.
  18. Of course for a 3D polygon, clockwise or counter-clockwise depends
  19. on which way you look at it. 
  20.  
  21. Brent Corkum
  22. corkum@csri.toronto.edu
  23.  
  24.  
  25. This function is also available via anonymous ftp at
  26.  
  27. boulder.civ.toronto.edu (128.100.14.11)
  28.  
  29. int the
  30.  
  31. pub/CCW_OR_CW
  32.  
  33. directory.
  34.  
  35.  
  36. P.S. Feel free to use and distribute this function. Any use or misuse
  37.      of this function is the responsibility of the user. If you
  38.      use this function, the header must remain in place to acknowledge
  39.      my contribution.
  40.  
  41. /*---------------------------cut here--------------------------------*/
  42. #include <stdio.h>
  43. #include <math.h>
  44. #define ABS(x) ((x)<0.0 ? -(x) : (x))
  45.  
  46. /*
  47. compile with:
  48.  
  49. cc <file.c> -lm
  50.  
  51. */
  52.  
  53. main()
  54. {
  55.   float pl[100];
  56.   int numv,i,flag;
  57.  
  58.   printf("Enter #numvertices: ");
  59.   scanf("%d",&numv);
  60.   for(i=1;i<=numv;++i){
  61.     printf("Enter Vertex %d: ",i);
  62.     scanf("%f%f",&pl[2*(i-1)],&pl[2*(i-1)+1]);
  63.   }
  64.   flag=Isclockwise(pl,numv);
  65.   if(flag==1) printf("polygon is clockwise\n");
  66.   else if(flag==0) printf("polygon is counter-clockwise\n");
  67.   else printf("invalid polygon\n");
  68. }
  69.   
  70.  
  71.  
  72. /* 
  73. Function by :
  74.  
  75. Brent Corkum
  76. Data Visualization Lab
  77. Civil Engineering
  78. University of Toronto
  79. Toronto Ontario Canada
  80. corkum@csri.toronto.edu or
  81. corkum@boulder.civ.toronto.edu (128.100.14.11)
  82.  
  83. That determines whether a 2d polygons vertices are orderred clockwise
  84. or counter-clockwise. The polygon is passed as an array of vertices
  85. (x1,y1,x2,y2,...,xn,yn where n=numv=#vertices or edges in the closed polygon).
  86. The function returns 1 if the polygon is clockwise and 0 if the polygon
  87. is counterclockwise. The function returns -1 if numv<3.
  88. */
  89.  
  90. int Isclockwise(pl,numv)
  91. float *pl;
  92. int numv;
  93. {
  94.   int index,pindex,aindex,i,flag;
  95.   float maxv,eps,dx,dy,adx,ady,xi,yi,xj,yj,xh,yh,xtest,trend;
  96.  
  97.   if(numv<3)return(-1);
  98.  
  99. /* calculate an epsilon for floating point comparisons */
  100.  
  101.   eps = 1e-5 * ABS(pl[0]);
  102.   if(eps<1e-5)eps=1e-5;
  103.  
  104. /* filter out last point if equal to first point */
  105.  
  106.   if(pl[0]==pl[2*(numv-1)] && pl[1]==pl[2*(numv-1)+1])--numv;
  107.  
  108. /* compute the vertex with the minimum x value, if there's more than one
  109.    compute the vertex that has the minimum x and y value (min vertex=P) */
  110.  
  111.   index=0;
  112.   for(i=1;i<numv;++i){
  113.     dx=pl[2*i]-pl[2*index];dy=pl[2*i+1]-pl[2*index+1];
  114.     adx = ABS(dx); ady = ABS(dy);
  115.     if(adx>eps){
  116.       if(dx<0.0)index=i;
  117.     }
  118.     else{
  119.       if(dy<0.0)index=i;
  120.     }
  121.   }
  122.  
  123. /* compute the previous vertex, making sure that the previous vertex does
  124.    not equal the min vertex (Pp)*/
  125.  
  126.   pindex=index;flag=1;
  127.   do{
  128.     --pindex;
  129.     if(pindex<0)pindex=numv-1;
  130.     dx=pl[2*pindex]-pl[2*index];dy=pl[2*pindex+1]-pl[2*index+1];
  131.     adx = ABS(dx); ady = ABS(dy);
  132.     if(adx>eps || ady>eps)flag=0;
  133.     else if(pindex==index)flag=0;
  134.   }while(flag);
  135.  
  136. /* compute the vertex coming after the min vertex, making sure that it
  137.    doesn't equal the min vertex (Pa)*/
  138.  
  139.   aindex=index;flag=1;
  140.   do{
  141.     ++aindex;
  142.     if(aindex==numv)aindex=0;
  143.     dx=pl[2*aindex]-pl[2*index];dy=pl[2*aindex+1]-pl[2*index+1];
  144.     adx = ABS(dx); ady = ABS(dy);
  145.     if(adx>eps || ady>eps)flag=0;
  146.     else if(aindex==index)flag=0;
  147.   }while(flag);
  148.  
  149. /* compute whether angle made by Pp -> P ->Pa is convex or concave,
  150.    the angle is measured counterclockwise from Pp->P */
  151.  
  152.   if(aindex != index && pindex != index){
  153.     xh = pl[2*pindex] ; yh = pl[2*pindex+1];
  154.     xi = pl[2*index] ; yi = pl[2*index+1];
  155.     xj = pl[2*aindex] ; yj = pl[2*aindex+1];
  156.  
  157. /* compute azimuth of Pp->P */
  158.  
  159.     dx = xi-xh ; dy = yi-yh;
  160.     if(dx==0.0 && dy==0.0) trend = 0.0;
  161.     else{
  162.       trend = atan2(dx,dy);
  163.       if(trend < 0.0) trend += 6.283185308;  /* += 2*PI */
  164.     }
  165.  
  166. /* rotate x value of Pp->P to positive y axis(x=0)  and x of
  167.    P-Pa by same angle */
  168.  
  169.     dx = xj-xi ; dy = yj-yi;
  170.     xtest = dx*cos(trend) - dy*sin(trend);
  171.  
  172. /* if xtest is >= 0.0 then you know that the angle between Pp->P and
  173.    P->Pa is CONVEX and therefore the polygon is clockwise */
  174.  
  175.     if(xtest>=0.0)return(1);
  176.     else return(0);
  177.   }
  178.   return(-1);
  179. }
  180.