Polygons

Fastgraph includes functions for drawing filled and unfilled polygons, as well as a function for determining if a given point is inside a convex polygon. All the polygon functions observe the clipping limits.

The fg_polygon() function draws an unfilled polygon in screen space. It requires an array of integer x coordinates as its first parameter, and an array of integer y coordinates as its second parameter. Each (x,y) coordinate pair from the two arrays is treated as a polygon vertex. In other words, the x coordinate of the first polygon vertex is the first element of the x coordinate array, and the y coordinate of the first vertex is the first element of the y coordinate array. Similarly, the second elements of each array define the second vertex, and so forth. The third parameter for fg_polygon() is an integer quantity that specifies the number of elements in the two coordinate arrays (that is, the number of polygon vertices).

Another function, fg_polygonw(), draws an unfilled polygon in world space. The fg_polygonw() function is the same as the fg_polygon() function, except its x and y coordinate arrays must contain floating point world space coordinates instead of integer screen space values.

Polygon drawing begins at the first vertex specified in the coordinate arrays. The polygon functions then draw a solid line to the second vertex, then to the third vertex, and continue in this manner through the last vertex. If necessary, they then close the polygon by drawing a line connecting the last vertex and the first vertex. For example, we can draw unfilled polygons using fg_polygon() as shown here:

C/C++:

#define VERTICES 10
int x[] = {200,300,400,400,300,240,160,160,200,210};
int y[] = {100, 80,100,220,320,320,240,200,160,150};
fg_polygon(x,y,VERTICES);

Delphi:

const  VERTICES = 10;
  x : array [1..VERTICES] of integer =
    (200,300,400,400,300,240,160,160,200,210);
  y : array [1..VERTICES] of integer =
    (100, 80,100,220,320,320,240,200,160,150);
begin
  fg_polygon(x,y,VERTICES);

Visual Basic:

Const VERTICES As Long = 10
Dim X(10) As Long
Dim Y(10) As Long
Call fg_setcolor(19)
X(0) = 200: X(1) = 300: X(2) = 400: X(3) = 400: X(4) = 300
X(5) = 240: X(6) = 160: X(7) = 160: X(8) = 200: X(9) = 210
Y(0) = 100: Y(1) = 80: Y(2) = 100: Y(3) = 220: Y(4) = 320
Y(5) = 320: Y(6) = 240: Y(7) = 200: Y(8) = 160: Y(9) = 150
Call fg_polygon(X(0), Y(0), VERTICES)

As shown in this example, fg_polygon() expects the x and y components defining the polygon vertices to be in separate arrays. Another function, fg_polyline(), draws an unfilled polygon from polygon vertices in one integer array. With fg_polyline(), the first array element is the x component of the first vertex, the second element is the y component of the first vertex, the third element is the x component of the second vertex, and so forth. The first fg_polyline() parameter is the vertex coordinate array of alternating x and y components, and the second parameter specifies the number of vertices. In other respects, fg_polyline() is identical to fg_polygon().

An additional feature available with fg_polyline() but not with fg_polygon() is the ability to specify vertex offsets. The fg_polyoff() function's two integer parameters respectively define offset values that are added to each fg_polyline() vertex. This makes it possible to define polygon vertices as relative values, that when combined with the offsets, determine the polygon's absolute position.

Perhaps the most important polygon display function is fg_polyfill(), which displays a filled convex polygon in screen space (the polygon is filled with pixels of the current color). Its first parameter is a vertex array in the same format used by fg_polyline(). The next parameter is obsolete and should be set to NULL (in earlier versions of Fastgraph, it was the name of a work array used internally by the fg_polyfill() function). The final parameter specifies the number of polygon vertices.

Our next example illustrates the use of fg_polyline(), fg_polyoff(), and fg_polyfill(). We first draw an unfilled polygon on the left, and then a filled version of the same polygon on the right. In each case, the positioning is accomplished by passing appropriate values to fg_polyoff(). Next we establish a clipping region in the lower right corner and redraw the filled polygon at the same position but in a different color. This results in only a portion of the filled polygon being drawn.

C/C++:

#define VERTICES 10
int xy[] = {200,100, 300, 80, 400,100, 400,220, 300,320,
            240,320, 160,240, 160,200, 200,160, 210,150};
fg_setcolor(11);
fg_polyoff(-120,-25);
fg_polyline(xy,VERTICES);
fg_polyoff(200,-25);
fg_polyfill(xy,NULL,VERTICES);
fg_setcolor(12);
fg_setclip(480,639,175,479);
fg_polyfill(xy,NULL,VERTICES);

Delphi:

const
  VERTICES = 10;
  xy : array [1..VERTICES*2] of integer =
    (200,100, 300, 80, 400,100, 400,220, 300,320,
     240,320, 160,240, 160,200, 200,160, 210,150);
begin
  fg_setcolor(11);
  fg_polyoff(-120,-25);
  fg_polyline(xy,VERTICES);
  fg_polyoff(200,-25);
  fg_polyfill(xy,nil^,VERTICES);
  fg_setcolor(12);
  fg_setclip(480,639,175,479);
  fg_polyfill(xy,nil^,VERTICES);

Visual Basic:

Const VERTICES As Long = 10
Dim XY(10 * 2) As Long
XY(0)=200: XY(1)=100: XY(2)=300: XY(3)=80
XY(4)=400: XY(5)=100: XY(6)=400: XY(7)=220
XY(8)=300: XY(9)=320: XY(10)=240: XY(11)=320
XY(12)=160: XY(13)=240: XY(14)=160: XY(15)=200
XY(16)=200: XY(17)=160: XY(18)=210: XY(19)=150
Call fg_setcolor(11)
Call fg_polyoff(-120, -25)
Call fg_polyline(XY(0), VERTICES)
Call fg_polyoff(200, -25)
Call fg_polyfill(XY(0), Null, VERTICES)
Call fg_setcolor(12)
Call fg_setclip(480, 639, 175, 479)
Call fg_polyfill(XY(0), Null, VERTICES)

The fg_polyfill() function fills convex polygons. Fastgraph considers a polygon to be convex if any horizontal line drawn through the polygon crosses the left edge exactly once and the right edge exactly once (excluding horizontal and zero-length edge segments). Note that this definition includes shapes that are not convex in the traditional sense. In addition, any non-convex polygon can be decomposed into two or more convex polygons. All triangles (that is, three-vertex polygons) are by their nature convex.

The filled convex polygon is a basic tool of three-dimensional computer graphics. A common practice is to build an image or object from several adjacent or connecting polygons. Such polygons typically overlap at one or more edges. For instance, the coordinates defining the right edge of one polygon may also define the left edge of another polygon immediately to its right. For an overall image to appear correct, its component polygons must fit together correctly. By default, fg_polyfill() applies the following rules to handle overlapping polygon edges:

  1. Points located exactly on non-horizontal edges are drawn only if the polygon's interior is directly to the right.

  2. Points located exactly on horizontal edges are drawn only if the polygon's interior is directly below them.

  3. A vertex is drawn only if all lines ending at that point meet the above two conditions.

These three rules guarantee that no pixel is drawn more than once when filling adjacent polygons. However, this behavior may not be suitable for displaying polygons that are not adjacent, because some or all of the pixels on the polygon's right and bottom edges will be excluded. If this is an issue, you can use fg_polyedge() to force fg_polyfill() to include all edge pixels. The fg_polyedge() function expects a single integer parameter. If it is zero, fg_polyfill() will include all edge pixels when drawing convex polygons. Passing any other value to fg_polyedge() restores the default behavior of excluding pixels that meet the criteria described above.

The final Fastgraph polygon function is fg_inside(), which checks if a specified point lies inside a convex polygon. Its first parameter is a vertex array in the same format used by fg_polyline() and fg_polyfill(). The second parameter is the number of vertices in the polygon, while the last two parameters specify the screen space x and y coordinates of the point being tested. The fg_inside() function returns 1 if the point lies inside the polygon and 0 if not. If the vertex array does not define a convex polygon, the return value is undefined. The fg_polyoff() offsets are applied to the fg_inside() vertex array, but not to the test point.

<< Prev

Next >>

Contents
Fastgraph Home Page

 

copyright 2001 Ted Gruber Software, Inc.