home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff267.lzh / Diglib / diglib.zoo / diglib / GSFILL.FOR < prev    next >
Text File  |  1989-06-20  |  5KB  |  182 lines

  1.         SUBROUTINE GSFILL(X,Y,N,TX,TY)
  2.         DIMENSION X(N),Y(N), TX(N),TY(N)
  3. C
  4. C       DIGLIB POLYGON FILL SUPPORT
  5. C       DERIVED FROM "HATCH" ALGORITHM BY KELLY BOOTH
  6. C
  7.         INCLUDE GCDCHR.PRM
  8.         INCLUDE GCDPRM.PRM
  9.         INCLUDE GCLTYP.PRM
  10. C
  11.         DIMENSION XINS(40)
  12.         INTEGER GSIVIS
  13.         LOGICAL LEFT
  14.         DATA FACT /16.0/
  15. C
  16. C       *****
  17. C       DEFINE ARITHMETIC STATEMENT FUNCTION TO MAPPING VERTICES
  18.         YMAP(YYY) = 2.0*AINT(YSCALE*YYY+0.5)+1.0
  19. C       *****
  20. C
  21.         IF (N .LT. 3) RETURN
  22. C
  23. C
  24. C       CONVERT TO ABSOLUTE COORD.
  25. C
  26.         DO 10 I=1,N
  27.                 CALL GSRST(X(I),Y(I),TX(I),TY(I))
  28. 10              CONTINUE
  29.         CALL MINMAX(TY,N,YMIN,YMAX)
  30.         CALL MINMAX(TX,N,XMIN,XMAX)
  31. C
  32. C       IF CLIPPING NEEDED OR IF NO HARDWARE POLYGON FILL, USE SOFTWARE
  33. C
  34.         IF ((GSIVIS(XMIN,YMIN) .NE. 0) .OR.
  35.      1   (GSIVIS(XMAX,YMAX) .NE. 0) .OR.
  36.      2   (IAND(IDVBTS,256) .EQ. 0)) GO TO 200
  37. C
  38. C       IF CAN HANDLE CONCAVE POLYGONS, JUST CALL DRIVER
  39. C
  40.         IF ((IAND(IDVBTS,512) .EQ. 0) .OR.
  41.      1   (N .EQ. 3)) GO TO 150
  42. C
  43. C       IF HERE, DRIVER CAN HANDLE CONVEX NON-INTERSECTING POLYGONS ONLY,
  44. C        SO MAKE SURE THIS POLYGON IS CONVEX AND NON-SELF-INTERSECTING.
  45. C
  46.         DX1 = X(1)-X(N)
  47.         DY1 = Y(1)-Y(N)
  48. C       !OLD NON-ZERO DELTA-Y
  49.         DY = DY1
  50. C       NUMBER OF TIMES DELTA-Y CHANGES SIGN
  51.         NCHNGS = 0
  52.         L = 1
  53.         COSTH = 0.0
  54. 110     CONTINUE
  55. C
  56. C               CONVEXITY TEST
  57. C
  58.                 DX2 = X(L+1)-X(L)
  59.                 DY2 = Y(L+1)-Y(L)
  60.                 A = DX1*DY2-DX2*DY1
  61.                 IF (A*COSTH .LT. 0.0) GO TO 200
  62.                 IF (COSTH .EQ. 0.0) COSTH = A
  63. C
  64. C               SELF INTERSECTION CHECK - RELYS ON "CONVEXITY" CHECK
  65. C
  66.                 IF (DY .NE. 0.0) GO TO 120
  67.                         DY = DY2
  68.                         GO TO 130
  69. 120             CONTINUE
  70.                 IF (DY2*DY .GE. 0.0) GO TO 130
  71.                         DY = DY2
  72.                         NCHNGS = NCHNGS + 1
  73.                         IF (NCHNGS .GE. 3) GO TO 200
  74. 130             CONTINUE
  75.                 DX1 = DX2
  76.                 DY1 = DY2
  77.                 L = L + 1
  78.                 IF (L .LT. N) GO TO 110
  79. 150     CONTINUE
  80.         CALL GSDRVR(1024+N,TX,TY)
  81.         RETURN
  82. C
  83. C       **********
  84. C       SOFTWARE FILL
  85. C       **********
  86. C
  87. 200     CONTINUE
  88. C
  89. C       FILLING A POLYGON IS VERY SIMPLE IF AND ONLY IF THE VERTICES OF
  90. C        THE POLYGON NEVER LIE ON A SCAN LINE.   WE CAN FORCE THIS TO HAPPEN
  91. C        BY THE FOLLOWING TRICK: MAKE ALL VERTICES LIE JUST BARELY ABOVE
  92. C        THE SCAN LINE THEY SHOULD LIE ON.   THIS IS DONE BY MAPPING THE
  93. C        VERTICES TO A GRID THAT IS "FACT" TIMES THE DEVICE RESOLUTION,
  94. C        AND THEN DOUBLING THE GRID DENSITY, AND OFFSETTING THE VERTICES
  95. C        BY 1.   BECAUSE WE DO THIS, WE MUST OUTLINE THE POLYGON.
  96. C
  97. C       *******
  98. C
  99. C       FILL WITH SOLID LINES
  100. C
  101.         LINOLD = ILNTYP
  102.         ILNTYP = 1
  103. C
  104.         LEFT = .TRUE.
  105.         YSCALE = YS*YRES*FACT
  106.         DLINES = 2.0*FACT
  107.         CALL MINMAX(Y,N,YMIN,YMAX)
  108.         YMIN = AINT(YMAP(YMIN)/DLINES)*DLINES+DLINES
  109.         YMAX = AINT(YMAP(YMAX)/DLINES)*DLINES
  110.         YSCAN = YMIN
  111. 210     CONTINUE
  112.                 INISEC = 0
  113.                 IFIRST = 0
  114. C
  115. C               DO EACH SIDE OF THE POLYGON. PUT ANY X INTERSECTIONS
  116. C               WITH THE SCAN LINE Y=YSCAN IN XINS
  117. C
  118.                 YBEGIN = YMAP(Y(N))
  119.                 XBEGIN = X(N)
  120.                 DO 400 L = 1, N
  121.                         YEND = YMAP(Y(L))
  122.                         DY = YSCAN-YBEGIN
  123.                         IF (DY*(YSCAN-YEND) .GT. 0.0) GO TO 390
  124. C
  125. C                       INSERT AN INTERSECTION
  126. C
  127.                         INISEC = INISEC + 1
  128.                         XINS(INISEC) = DY*(X(L)-XBEGIN)/(YEND-YBEGIN)+XBEGIN
  129. C
  130. 390                     CONTINUE
  131.                         YBEGIN = YEND
  132.                         XBEGIN = X(L)
  133. 400                     CONTINUE
  134. C
  135. C               FILL IF THERE WERE ANY INTERSECTIONS
  136. C
  137.                 IF (INISEC .EQ. 0) GOTO 500
  138. C
  139. C               FIRST WE MUST SORT ON X INTERSECTION.
  140. C               USE BUBBLE SORT BECAUSE USUALLY ONLY 2.
  141. C               WHEN "LEFT" IS TRUE, ASCENDING SORT, FALSE IS DESCENDING SORT
  142. C
  143.                 DO 450 I =  1, INISEC-1
  144.                         XKEY = XINS(I)
  145.                         DO 430 J = I+1, INISEC
  146.                                 IF (.NOT. LEFT) GOTO 420
  147.                                 IF (XKEY .GE. XINS(J)) GO TO 430
  148. 410                             CONTINUE
  149.                                 TEMP = XKEY
  150.                                 XKEY = XINS(J)
  151.                                 XINS(J) = TEMP
  152.                                 GO TO 430
  153. 420                             IF (XKEY .GT. XINS(J)) GOTO 410
  154. 430                             CONTINUE
  155.                         XINS(I) = XKEY
  156. 450                     CONTINUE
  157. C
  158. C               DRAW FILL LINES NOW
  159. C
  160.                 YY = YSCAN/(2.0*YSCALE)
  161.                 DO 460 I = 1, INISEC, 2
  162.                         CALL GSMOVE(XINS(I),YY)
  163.                         CALL GSDRAW(XINS(I+1),YY)
  164. 460                     CONTINUE
  165. 500             CONTINUE
  166.         YSCAN = YSCAN + DLINES
  167.         LEFT = .NOT. LEFT
  168.         IF (YSCAN .LE. YMAX) GO TO 210
  169. C
  170. C       FINALLY, OUTLINE THE POLYGON
  171. C
  172.         CALL GSMOVE(X(N),Y(N))
  173.         DO 510 L=1,N
  174.                 CALL GSDRAW(X(L),Y(L))
  175. 510             CONTINUE
  176. C
  177. C       RESTORE LINE TYPE
  178. C
  179.         ILNTYP = LINOLD
  180.         RETURN
  181.         END
  182.