Function GraArc() Foundation

Draws a circle, arc, or ellipse.

Syntax
GraArc( [<oPS>], [<aCenter>], <nRadius>, ;
        [<aEllipse>], [<nStartAngle>], ;
        [<nSweepAngle>], [<nFill>] ) --> lSuccess
Parameters
<oPS>
The argument <oPS> specifies a presentation space in which the circle (arc) is drawn. If the current window is an XbpCrt window, <oPS>is optional. If it is NIL, the return value of SetAppWindow():presSpace() is used. In all other cases <oPS> is not optional. It must be created either using XbpPresSpace():new() or a "Micro PS" must be requested from an Xbase Part using the method:lockPS(). After graphic output the Micro PS must be released with :unlockPS().
<aCenter>:= { <nX0>, <nY0> }
<aCenter> is an array of two elements which determines the coordinates for the center point of the circle. The first element <nX0> specifies the x coordinate and the second element <nY0>specifies the y coordinate. The unit for the coordinates depends on the coordinate system defined for the presentation space. If no presentation space is specified, values for the coordinates are given in pixels, which is the unit for a window. The origin for the coordinates (the point {0,0}) is at the lower left. If <aCenter> is not specified, the center point of the circle is the current pen position.
<nRadius>
<nRadius> is a positive integer which indicates the radius of the circle.
<aEllipse> := { <nX1>, <nY1>, <nX2>, <nY2> }
The parameter <aEllipse> is needed to draw an ellipse. It is an array with four elements which designates the end points of both ellipse axes. The coordinates of both endpoints are calculated by the following equations (see sections "Description" and "Example"):
nXhorizontal := nX0 + nRadius * nX1  // ellipse axis in the 
nYhorizontal := nY0 + nRadius * nY1  // x direction (horizontal) 

nXvertical   := nX0 + nRadius * nX2  // ellipse axis in the 
nYvertical   := nY0 + nRadius * nY2  // y direction (vertical) 
The default value of <aEllipse> is {1,0,0,1}.
<nStartAngle>
<nStartAngle> determines the starting point from which an arc is drawn. It is a positive integer which indicates the number of degrees the starting point of the arc deviates in the counter clockwise direction from horizontal.
<nSweepAngle>
<nSweepAngle> is a positive integer which indicates the opening angle for the arc in degrees.
<nFill>
The optional argument <nFill> specifies whether a circle is drawn as an outline or is filled. The following table shows the possible #define constants from the file GRA.CH to use for <nFill>:
Fill attributes for GraArc()
Constant Description
GRA_FILL Fills circle
GRA_OUTLINE *) Draws an outlined circle
GRA_OUTLINEFILL Draws an outlined and filled circle
  1. Default value
Note: When drawing an arc, <nFill> cannot be used.
Return

The return value of GraArc() is .T. (true) if the circle was drawn, otherwise it is .F. (false). If the return value is .F., the cause of error can be determined using GraError().

Description

Circles, arcs and ellipses are drawn using the function GraArc(). By default a circle is drawn as an outline with the color and the line width set by the function GraSetAttrLine(). The fill pattern and fill color for a filled circle can be specified with GraSetAttrArea(). The default for the fill pattern is the #define constant GRA_SYM_SOLID.

Ellipses and arcs drawn with GraArc()

Drawing ellipses

For drawing ellipses, the coordinates for the end points of the ellipse axes must be indicated in addition to the center point. These are calculated from the values in <aEllipse>. The length of the axis is calculated by multiplication with the radius. The following calls all result in the same ellipse:

GraArc(, {200,300}, 40, { 2,0,0, 1} ) 
GraArc(, {200,300},  4, {20,0,0,10} ) 
GraArc(, {200,300},  1, {80,0,0,40} ) 

It is recommended that the value 1 be set as the radius when drawing an ellipse, since this causes the values in <aEllipse> to exactly represent the relative coordinates for both ellipse axes. The origin for both axes is the center point of the ellipse.

If values not equal to zero are entered for the array elements <nY1> and <nX2>, the ellipse axes are tipped over and the ellipse drawn turned. To avoid a distorted ellipse be sure that the ellipse axes are always at a 90 angle to each other.

Drawing arcs

An arc begins with the starting angle <nStartAngle> and is drawn to the angle <nStartAngle> + <nSweepAngle>. It is drawn only as a line and cannot be filled. Thus, <nFill> cannot be used when drawing an arc. If it is included, a runtime error occurs.

As is apparent from the illustration, with an arc a straight line is always drawn beginning at the current pen position up to the intersection point with the radius of the arc. The arc is drawn out from this intersection point. The pen position does not change. To assure that the line begins at the center point of the arc, the pen position must be set to the center point with GraPos() before calling GraArc().

To fill arcs with a pattern they must be defined within a graphic path with GraPathBegin() / GraPathEnd(). The path can then be filled or outlined (see the third example for GraArc()).

Examples
Drawing concentric circles

// In this example 5 concentric circles are drawn with GraArc(). 
// The radius is raised 30 pixels in each case. 

PROCEDURE Main 
   LOCAL i 

   SetColor("N/W")                     // fill window with pale gray 
   CLS 

   FOR i:=1 TO 5 
       GraArc( NIL, {300,200}, 30*i )  // draws circle 
   NEXT 

   Inkey(0)                            // waits for key stroke 
RETURN 
Construction of an ellipse and arc

// This example program was used to create the illustration with an 
// ellipse and arcs. 

#include "Gra.ch" 

PROCEDURE Main 
   LOCAL nX0, nY0, nX1, nY1, nX2, nY2, aAttr 

   SetColor("N/W")                  // fill window with pale gray 
   CLS 

   aAttr := Array( GRA_AM_COUNT ) 
   aAttr [ GRA_AM_SYMBOL ] := GRA_MARKSYM_SMALLCIRCLE 
   GraSetAttrMarker( NIL, aAttr ) 

   nX0 := 150                       // center point of 
   nY0 := 150                       // the ellipse 

   nX1 := 120                       // length in x direction 
   nY1 := 0                         // deviation horizontally 
   nX2 := 0                         // deviation vertically 
   nY2 := 75                        // length in y direction 

                                    // draw ellipse: Radius=1 
   GraArc( NIL, {nX0, nY0}, 1, {nX1, nY1, nX2, nY2} ) 
   GraMarker( NIL, {nX0, nY0} ) 
   GraStringAt( NIL, {nX0-35, nY0-20}, "{nX0,nY0}" ) 

                                    // horizontal axis 
   GraLine( NIL, {nX0, nY0}, {nX0+nX1, nY0+nY1} ) 
   GraMarker( NIL, {nX0+nX1,nY0+nY1} ) 
   GraStringAt( NIL, {nX0+nX1+10, nY0+nY1-5}, "{nX1,nY1}" ) 

                                    // vertical axis 
   GraLine( NIL, {nX0, nY0}, {nX0+nX2, nY0+nY2} ) 
   GraMarker( NIL, {nX0+nX2,nY0+nY2} ) 
   GraStringAt( NIL, {nX0+nX2-35, nY0+nY2+10}, "{nX2,nY2}" ) 

   nX0 := 490                       // new coordinates for 
   nY0 := 150                       // arcs 
   nX1 := nX0 
   nY1 :=  50 

   GraPos( NIL, {nX0,nY0} )         // GraPos() is the mid-point 
   GraArc( NIL, {nX0,nY0}, 100, {1,0,0,1}, 30, 100) 
   GraMarker( NIL, {nX0,nY0} ) 
   GraStringAt( NIL, {nX0-100, nY0+50}, "GraPos() == {nX0,nY0}" ) 

   aAttr := Array( GRA_AL_COUNT )   // set line attributes 
   aAttr [ GRA_AL_TYPE ] := GRA_LINETYPE_LONGDASH 
   GraSetAttrLine( NIL, aAttr ) 

   GraPos( NIL, {nX1,nY1} )               // GraPos() is not the 
   GraArc( NIL, {nX0,nY0}, 120,, 30, 100) // mid-point 
   GraMarker( NIL, {nX1,nY1} ) 
   GraStringAt( NIL, {nX0-100, nY1-20}, "GraPos() <> {nX0,nY0}" ) 

   Inkey(0)                               // wait for key press 
RETURN 
Draw a pie chart with filled arcs

// In the example the function DrawFilledPartialArc() is programmed 
// to draw filled arcs. This function is used for drawing a pie chart. 
// An arc is filled using GraPathFill(). The path definition occurs 
// within a segment. 

#include "Gra.ch" 

PROCEDURE Main 
   LOCAL nX, nY, nRadius,  nStartAngle, aAngle, aPattern, i 

   SetColor("N/W")                  // fill window with pale gray 
   CLS 

   nX       := 300                  // mid-point of the 
   nY       := 200                  // pie chart 
   nRadius  := 150                  // radius 
   aAngle   := { 30, 100, 15, 75, 80, 60 } 
   aPattern := { ;                  // various fill attributes 
      GRA_SYM_DENSE2, ; 
      GRA_SYM_DIAG1 , ; 
      GRA_SYM_DENSE4, ; 
      GRA_SYM_DIAG2 , ; 
      GRA_SYM_DENSE6, ; 
      GRA_SYM_DIAG3   } 

   nStartAngle := 45                // starting angle 

   FOR i:=1 TO LEN( aAngle )        // draw filled arcs 
      DrawFilledPartialArc( {nX, nY}, nRadius, ; 
                            nStartAngle, aAngle[i], ; 
                            aPattern[i], .T. ) 
      nStartAngle += aAngle[i]      // increment starting angle 
   NEXT 

   Inkey(0)                         // wait for key press 

RETURN 

***************************************** 
* Draws filled arcs                     * 
***************************************** 
FUNCTION DrawFilledPartialArc( aCenter, ; 
                               nRadius, ; 
                               nStartAngle, ; 
                               nSweepAngle, ; 
                               nPattern , ; 
                               lOutline ) 
   LOCAL aAttr, nSegment 

   aAttr := Array( GRA_AA_COUNT )   // select fill pattern 
   aAttr [ GRA_AA_SYMBOL ] := nPattern 
   aAttr := GraSetAttrArea( NIL, aAttr ) 

                                    // open segment 
   nSegment := GraSegOpen( NIL, GRA_SEG_MODIFIABLE ) 
      GraPathBegin()                // define path 
         GraPos( NIL, aCenter )     // define arc 
         GraArc( NIL, aCenter, nRadius,, nStartAngle, nSweepAngle ) 

      GraPathEnd( NIL, .T. )        // end path definition 
   GraSegClose()                    // close segment 

   GraSegDraw( NIL, nSegment )      // create path for drawing 
   GraPathFill()                    // fill path 

   IF lOutline 
      GraSegDraw( NIL, nSegment )   // recreate path 
      GraPathOutline()              // outline path 
   ENDIF 

   GraSegDestroy( NIL, nSegment)    // delete segment 
   GraSetAttrArea( NIL, aAttr )     // reset old attributes 

RETURN NIL 
Feedback

If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.