Here is some information I have found about the difference between WINDING and ALTERNATE.
When filling a polygon with colour, it is necessary to decide whether a given point is 'inside' or 'outside' the polygon. Obviously only 'inside' points should be changed to the fill colour.
The ALTERNATE and WINDING parameters determine the method used by the GDI [Graphics Device Interface] to decide whether a particular point [pixel] is 'inside' the polygon to be filled. Windows draws an imaginary left-to-right horizontal line from the point to infinity and notes where this line cuts edges of the polygon.
WINDING: Each time the horizontal line cuts an edge that was drawn in the anticlockwise direction (right-to-left or bottom-to-top) the point's winding number is incremented. Similarly, Each time the line cuts an edge that was drawn in the clockwise direction (left-to-right or top-to-bottom) the point's winding number is decremented. Those points that end up with a non-zero winding number are deemed to be 'inside' points.
ALTERNATE: Each time the horizontal line cuts an edge, a counter is incremented. Those points that end up with the counter having an odd value are deemed to be 'inside' points.
Frequently ALTERNATE and WINDING produce the same result, but when they do not, WINDING tends to fill more points than ALTERNATE.
WINDING is slower but tends to produce better results with complex polygons in which [some of] the edges intersect one another and/or with polygons that contain closed interior regions (i.e. chid polygons).
(The last two paragraphs are my own interpretion and may be wrong.)
Here is a program using ALTERNATE and WINDING:
Code: Select all
; Polygon AKJ 04-Sep-04
; SetPolyFillMode_() Demo
; Read polygon co-ordinates (5-pointed star)
Dim ps.Point(4) ; Array of 5 POINT structures
For p=0 To 4: Read ps(p)\x: Read ps(p)\y: Next p
DataSection
Data.l 60,10, 20,100, 115,42, 5,42, 100,100
EndDataSection
; GUI constants
Enumeration 1
#winMain
#imgPolygon ; Image gadget
EndEnumeration
; GUI metrics
gap=20 ; Border
imgw=140: imgh=imgw*2 ; ImageGadget
winw=imgw+gap*2: winh=imgh+gap*2 ; Window
; Create GUI, ignoring errors (let the debugger catch them)
flags= #PB_Window_SystemMenu
OpenWindow(#winMain,0,0,winw,winh,flags,"Poly Fill Mode")
CreateGadgetList(WindowID())
ImageGadget(#imgPolygon,gap,gap,0,0,0,#PB_Image_Border) ; Width, height will be that of image
; Define colours
red=RGB(255,0,0)
green=RGB(0,255,0)
; Define drawing area
CreateImage(#PB_Any,imgw,imgh)
hDC=StartDrawing(ImageOutput())
; Set the background to red
BackColor(Red(red),Green(red),Blue(red)) ; I wish the syntax was better !!!
Box(0,0,imgw,imgh,red) ; Would be nice to have a Cls() facility !!!
; Set the foreground to green
FrontColor(Red(green),Green(green),Blue(green)) ; I wish the syntax was better !!!
; Draw first closed polygon
Locate(0,0): DrawText(" ALTERNATE") ; The default fill mode
SetWindowOrgEx_(hDC,0,-15,#Null) ; Move origin downwards
Polygon_(hDC,@ps(0),5)
; Draw second closed polygon below the first
SetWindowOrgEx_(hDC,0,-145,#Null)
Locate(0,0): DrawText(" WINDING")
SetPolyFillMode_(hDC,#WINDING)
SetWindowOrgEx_(hDC,0,-160,#Null) ; The new origin is relative to the original origin
Polygon_(hDC,@ps(0),5)
; Release device context
StopDrawing()
; Display the drawing in an image gadget so that it is persistent
SetGadgetState(#imgPolygon,ImageID()) ; Must have ImageID() or UseImage(#image)
; AKJ standard skeleton event loop
done=#False
Repeat
ev = WaitWindowEvent()
If ev=#PB_EventMenu: ev=#PB_EventGadget: EndIf ; To map shortcut keys to gadgets
Select ev
Case #PB_Event_Gadget
Select EventGadgetID()
; !!!
EndSelect
Case #PB_Event_CloseWindow
done=#True
EndSelect
Until done
CloseWindow(#winMain)
End