Next Previous Contents

6. More complex examples

Having covered the majority of the commands needed to use successfully GLE we now turn to some of the more specialized commands that may be useful in some applications.

6.1 Adding existing graphics to a GLE script

In many cases we may wish to include an existing graphic within a GLE file. It may be a supplied company logo or advertisement, or it may be a file that has been drawn previously with GLE or another graphics package. GLE can add graphics at any point on the page, provided the graphic files are in one of two common formats, Postscript or TIFF.




6.2 Coordinate transforms

Within a GLE program it is often possible to denote a section of code that is referred to a different coordinate system to take advantage of a symmetry within the diagram. The coordinate transforms all begin with a begin command and end with an end command, everything in between these two lines is treated within the separate system. At the end command GLE restores both the reference point and graphic state, including line styles and font heights, that was present before the begin command.

We have already met the most basic coordinate transform, that of a translation. We used the begin origin transform in the super-ellipse, it allows us to refer to an origin that differs from the origin of the page. A useful command when we have a subroutine or need to draw something with amove and aline, we can reposition the object just by moving to a different point before the begin origin command.

Rotations

The begin rotate command allows us to draw an object then rotate it by an angle.


!rotate.gle - Rotates some text
size 5 5
set hei 0.3
amove 1 2
begin rotate 40
        text This text has been rotated 
end rotate

This will rotate the given text by an angle of 40° anti-clockwise.

We look at a more concrete example that incorporates both of the above techniques and also produces a useful image.


!protrac.gle - Demonstrates the begin rotate and origin commands

size 18 18

set font plsr   !Defines the variables for easy alterations
set hei 0.4
a=8
b=0.3
c=1
d=0.65
f=6
g=6
amove 9 9

begin origin               !Sets the origin to 9 9

        for i=0 to 359     !Draws the small unit angle ticks
        begin rotate i
                amove 0 a
                rline 0 -b
        end rotate
        next i

             !Draws the longer marks and labels every 10°        set color blue
        for i=0 to 350 step 10
        begin rotate i
                amove 0 a
                rline 0 -c
                if i>0 then
                        rmove -0.2 -0.5
                        else
                        rmove -0.1 -0.5
                        end if
                write i
                 end rotate
         next i

             !Draws the small 5° marks
        set color green
        for i=5 to 355 step 10
        begin rotate i
                amove 0 a
                rline 0 -d
                end rotate
        next i

             !Draws the long central lines every 10°        set color red
        for i=0 to 350 step 10
        begin rotate i
                amove 0 0
                aline 0 g
                end rotate
        next i

             !Draws a black circle in the middle
        set color black
        amove 0 0
        circle 0.3
        amove -f 0
        aline f 0
        amove 0 -f
        aline 0 f
        amove 0 0

        end origin

We can see that the use of the rotate command greatly simplifies the drawing of the protractor - it is only neccessary to draw the lines and labels on a single straight line, the rotate command takes care of the rest of the shape.

Scaling

In the same way as we rotated objects we may also scale them in the x and y directions,


!scale.gle - demonstrates the scale command
size 10 10
amove 1 1
begin scale 3 1
        begin rotate 30
                text hello
                end rotate
        end scale

The numbers following the scale command represent the scaling factors in the x and y directions. A value of 1 will leave the object unchanged, greater than 1 will increase the size, less than 1 will decrease it. The example above rotates the text by 30°and then stretches it by a factor of 3 in the x direction. Notice that the scale and rotate operations are entirely independent of each other, so we can only scale a rotated object along its original axes. In the example above we talk of stretching along the ‘x direction’, but this direction is actually orietated at 30° to the x axis.

We can use the scale command to create the impression of a three dimensional object. The geometry behind these images, particularly if we wish to view an object from an arbritrary choice of angles, can get quite complex, and the independence of the scale and rotate commands can make seemingly simple shapes quite difficult to draw. The example below demonstrates a simple use of the scale command applied to a simple cuboid. Notice that to simplify the mathematics we restrict the viewing to a single plane along the diagonal of the object. More complex examples can be achieved but it must be said a dedicated 3-dimensional CAD package may, in this case, prove more fruitful.


!cube.gle - Demonstrates the use of the scale command to generate 3D objects
size 10 10
pi=3.1415

sub top a b                     !This draws the top of each cuboid
        gsave 
        x1=a*cos(pi/4)
        y1=a*sin(pi/4)
        x2=b*cos(pi/4)
        y2=b*sin(pi/4)
        save top1
        rline x1 y1
        save top2
        rline -x2 y2
        rline -x1 -y1
        save top3
        rline x2 -y2
        grestore
end sub

sub bottom a b                  !This draws the bottom of each cuboid
        gsave
        x1=a*cos(pi/4)
        y1=a*sin(pi/4)
        x2=b*cos(pi/4)
        y2=b*sin(pi/4)
        
        gsave
        save bottom1
        rline x1 y1
        save bottom2
        grestore
        rline -x2 y2
        save bottom3
        grestore
end sub 

sub side                        !This joins the top and bottom of a cuboid
        join top1 - bottom1
        join top2 - bottom2
        join top3 - bottom3
end sub

sub drawcube ang        !This combines the cuboid drawing into a single routine
                        !viewed from an angle theta above the bottom plane
begin scale 1 cos(ang)

@top 1 2
rmove 0 -1.5*tan(ang)
@bottom 1 2
end scale 
@side

end sub


amove 0 0                       !Draws the cuboid from various angles
box 5 5
rmove 2.5 0.5+2*sin(1)
@drawcube 1
amove 0 5
box 5 5 
rmove 2.5 0.5+2*sin(0.25)
@drawcube 0.25
amove 5 0
box 5 5 
rmove 2.5 0.5+2*sin(1.4)
@drawcube 1.4 
amove 5 5
box 5 5
rmove 2.5 0.5+2*sin(0.70)
@drawcube 0.70

Generally, the apperance of 3D images such as this can be improved by judicious use of colours and shading. To add shading to anything other than a rectangle we need to know how to define an object, this is covered in the section on path drawing.

6.3 Mathematical curves

Technical drawings may require curves that have a well defined mathematical shape. GLE has a set of commonly used curves for this purpose, although it may sometimes be neccessary to add a particularly unusual curve using the graph module.

A simple curve

The curve command will draw a smooth line through any number of points, with an initial and final gradient that must also be supplied by the programmer.


!curve.gle - demonstrates the use of the curve function
size 12 8

set lstyle 2

aline 1 1       !Draws the points the curve follows
rline 0 4
rline 4 0
rline 0 -4

set lstyle 0
amove 1 1       !The first and last two numbers represent the gradient,
                !the others are the relative position of the guide points
curve 1 1 0 4 4 0 0 -4 1 1

amove 7 0
set lstyle 2
rline 0 5
rline 4 0
rline 0 -4

set lstyle 0
amove 7 1       !Another curve with different initial and final gradients
curve 0 1 0 4 4 0 0 -4 0 -1

amove 6 7
set just cc
text Simple curves

The curve command has the following syntax,

curve 2 1 1 1 1 2 -1 -1
The curve is drawn starting from the initial coordinates with a gradient defined by the first two values following the curve command. In this case (2,1) represents an initial gradient of two units along the x axis and 1 unit up the y axis or an elevation of arctan(1/2) above the x axis. With the exception of the final pair, the numbers following the initial gradient represent the points the curve must pass through. They are given in terms of relative position vectors from the last point so (1,0), (0,1), (-1,0), and (0,-1) would trace out a square. The final pair of numbers gives the gradient the curve is to have as it passes through the final point.

Bezier cubic sections

Bezier sections are mathematical curves that were first used for car bodywork design in the 70s. They have a number of neat mathematical properties that make them particularly appropriate for computer graphics. Most of the curve drawing commands in graphics packages are based around some sort of Bezier section, and the design of computer fonts also relies heavily on them. GLE has a command that will draw a cubic (3rd degree) Bezier curve to a set of four control points.


!bezier.gle - Demonstrates Bezier cubic sections
size 18 12

amove 1 6
set lstyle 2
aline 1 10
aline 5 10
aline 5 6

amove 1 6
set lstyle 0
bezier 1 10 5 10 5 6


amove 11 11
set lstyle 2
aline 14 6
aline 15 11
aline 17 8

amove 11 11
set lstyle 0
bezier 14 6 15 11 17 8 

amove 1 1 
set lstyle 2
rline 4 4
rline 3 -4
rline 4 2
rline 2 1
rline 1 -1
rline 1 1

amove 1 1
set lstyle 0
rbezier 4 4 7 0 11 2
rbezier 2 1 3 0 4 1

amove 6 6
set hei 0.6
text Bezier cubic sections

There are two commands that can be used to draw bezier sections, the first, bezier, is followed by three sets of absolute coordinates,

bezier 1 2 2 4 3 6
This will draw a third degree polynomial through the starting point and the final coordinate, the other two control points define the form of the rest of the curve. The second command we can use is rbezier, this performs the same operation except the points are now defined in terms of relative coordinates from the start point.
rbezier 1 2 3 6 6 12
This will draw the same curve as the example above, but with relative coordinates. Notice that this is different from the curve command, where the relative points were taken from the last point instead of the overall start position.

A discussion of the mathematics behind Bezier sections is beyond our present purposes, an explanation can be found in the Postscript Language Reference Manuel or in texts on computer graphics. With experience it is fairly easy to see roughly where the final curve will lie. Because of the applications to computer graphics there are several sites on the internet that offer interactive drawing routines to play with, for example try http://www.cstc.org/data/resources/47/bezier.html.

Mathematically we can define a Bezier section with any number of control points, for each control point the fitted polynomial gains an extra degree - 6 control points will give a 5th degree polynomial. In practice we normally only use cubic sections (or parabolic sections) for most applications. More complex curves are built up from a series of cubic sections joined together. This saves on processing power and also allows small corrections to be made to a single point without affecting the entire curve.

We demonstrate the joining of two bezier sections in the last curve of the bezier.gle example. A continuous curve is trivially made by starting a new bezier from the end point of the last one. To match the first derivatives as well we note that the gradient at the beginning of the curve is given by the line joining the first two control points, and that the gradient at the end is given by the line joining the last two control points. The first derivative will then be continuous across the two Bezier sections if all three control points are collinear. It is not generally possible to ensure continuity of the second derivative across a curve boundary.

Circular arcs

We have already looked at the simple example of the circle, we may extend this to draw a small arc of a circle. GLE 3.5 (not 3.3) also supports a similar set of commands for drawing all, or portions, of an ellipse.

To draw a portion of a circle we use the arc command, where we must now specify the radius of the arc and the angles that we wish to draw it between. For example,

arc 2 10 20
which will draw an arc of radius 2cm in an anti-clockwise direction between 10° and 20°. The angular convention is as polar coordinates, with 0° at 3 o'clock and 90° at 12 o'clock. Angles can be given that are greater than 360°, and can be either positive or negative.

To draw an arc in the opposite direction, which can simplify some diagrams and is important when constructing paths, we use the narc command.

narc 1 10 20
amove xend() yend()
This will draw a 1cm arc from 20° to 10°, then move to the end of the arc at 10°. Notice that the command,
arc 1 20 10
amove xend() yend()
would have draw the arc in the anti-clockwise direction all the way around the origin.

We demonstrate the use of the arc command with an example showing the conditions for Frauenhofer diffraction.


!Frauenhofer.gle - The condition for frauenhofer diffraction
size 16 10

ang=17  
radius=14
amove 15 5

arc 4 180-ang 180
narc radius 180+ang 180-ang
rline -radius*cos(torad(ang)) radius*sin(torad(ang))

set lstyle 2
rline 0 -radius*sin(torad(ang)) 
save point1
rline 0 -radius*sin(torad(ang))
set lstyle 0
aline 15 5
set lstyle 3
rline -radius 0
save point2

set hei 0.5
join point1 <-> point2
rmove 0.2 0.1
text d

rmove radius/2 2.1
text R 

amove 12 5.2
text \theta

amove 9 2
set hei 0.3
begin text width 4
For Fraunhofer diffraction we require  d < \lambda/10 
end text

Unfortunately GLE is not consistent in its use of radians or degrees. Generally, mathematical expressions such as sin or tan require the input angle to be in radians, and the corresponding inverse hyperbolic functions output angles in radians. Fractions of circular and elliptical arcs are, however, specified in degrees. There are two useful functions that will convert between the two units, todeg and torad. Thus to find the sine of a 10° angle we write,

sin(torad(10))
And to find an angle in degrees,
angle = todeg(acot(3/4)
will give the variable angle the value in degrees of arccotan(34)/;.

In the example above we choose to work mainly in degrees, the conversion ratios being forced upon us when we use a combination of trigonometric ratios and amove commands. Such a combination may seem slightly clumsy. Why, for example could we not have written,

narc radius 180+ang 180-ang
rline xend() yend()
The answer is, of course, is that it will not work. GLE does not, unfortunately, support the use of the xend() and yend() command with either circular or elliptical arcs. On this occasion we are forced to resort to trigonometry to produce the effect we require. It is important to be aware of the limitations of some of the commands in GLE, as identifying unexpected errors caused by the failure of a command can be time consuming.

The arcto command

An adaptation of the arc command performs a commonly used routine: the connecting of two points by an arc of a given radius. We look at a simple example,


!arcto.gle - Demonstrates the arcto command
size 5 5

amove 1 1
set lstyle 2
aline 4 2
aline 1 4

amove 1 1
set lstyle 0
arcto 3 1 -3 2 0.5

This compares the straight (dotted) lines drawn with the curved arc. The command uses relative movement, with the qualifiers taking the form,
arcto x1 y1 x2 y2 rad
This draws a line from the current point to a point a vector (x1,y1) away, then another line a further vector (x2,y2) away. The lines are then replaced with a partial arc of radius rad instead of the vertex at (x1,y1).

Ellipses

The ellipse command is very similar to the circle command, except we must now specify the eccentricity of the ellipse. The syntax is,

ellipse 2 1 fill red
which will draw a red ellipse with major axis 2 and minor axis 1.

We look at a simple example of the use of ellipses that leads on to a more complex program in the following section.


!light.gle - demonstrates the use of ellipses and circles in the propagation of light
size 10 10

set just br lwidth 0.01 hei 0.3
amove 5 0.5                     !Draws a set of axis
aline 5 9.5 arrow end
text z
rmove 0.1 0.1
amove 0.5 5
aline 9.5 5 arrow end
rmove 0.1 0.1
text x
amove 5 5

set lwidth 0.05                 !Draws the ellipse and circle that represent the 
ellipse 4 3                     !propagation of the o-ray and e-ray.
set lstyle 2
circle 3

set just cl                     !Adds the direction of the optical axis
amove 5 5
set lstyle 0
rline 0 1 arrow end
text \glass \: Optical axis 

amove 6 1.5                     !Adds a key
rline 1 0 
text \glass \: e-ray
amove 6 1
set lstyle 2
rline 1 0 
text \glass \: o-ray 

The diagram shows the propagation of wavefronts in a birefringent material, the o-ray represents the component of the polarisation vector parallel to the y-axis (out of the page), and the e-ray represents the remaining component perpendicular to both the direction of propagation and the y axis. Notice that for light propagating along the optical axis the two polarisations are identical, but if there is a component of the electric field along the optical axis then the propagation speed is (in our example) greater.

Elliptical arcs

To illustrate the commands we look at a diagram to illustrate the different directions of propagation of light within a birefringent crystal. Such crystals have a directional anisotropy in the crystal binding forces, which produces a similar anisotropic effect in the rate of propagation of light through the crystal - light that has its polarisation vector in the direction of the anisotropy (the optical axis) will travel at a different speed (faster in our example) than light polarised orthogonal to the optical axis. Using Huygens construction we can represent the propagation of light through the crystal as a series of ellipses or circles. In practice, we illuminate the crystal with natural light containing both polarisations, the birefringent material will split the incoming light into two independent beams, one polarised along the optical axis and the other against it.


!oray.gle - Example of the use of ellipses and arcs

size 22 9.5             

inclination=5           !Sets the inclination of the optical axis to the
                        !crystal clevage plane

sub arcdraw n space ang         
gsave                   !Subroutine to draw an arc of a circle
set lwidth 0.001
rmove 0 (n-1)*space/2 
for i = 1 to n step 1
marker dot 0.2
arc 1 -ang ang
rmove 0 -space
next i
grestore
end sub

sub ellipsedraw n space ang inc
gsave
rmove 0 (n-1)*space/2   !Subroutine to draw an arc of an ellipse
set lwidth 0.001
begin rotate inc
for j = 1 to n step 1
marker dot 0.2
elliptical_arc 1 0.6 -ang-10 ang+10 
rmove 0 -space
next j
end rotate
grestore
end sub

sub drawcrystal         !Subroutine to draw the crystal rhombus
set lwidth 0.05
rline 0 7
rline 5 2
rline 0 -7
rline -5 -2
rline 0 7
end sub

sub move inc            !Subroutine to move along the crystal in a direction
a=cos(torad(inc))       !perpendicular to the optical axis
b=sin(torad(inc))
set lwidth 0.01
rline a b
set lwidth 0
end sub

sub drawaxis size                               !Subroutine to draw a set of
gsave                                           !xyz axis, this is a commonly
set lstyle 1 lwidth 0.01 hei 0.3 just bl        !used routine and could 
rline size 0 arrow end                          !probably be put in file
text x                                          !on its own
rmove -size size
text z
rline 0 -size arrow start
rline size*((sqrt(3))/2) size/2 arrow end
text y
grestore
end sub

amove 3 0.25            !Draws the first o-ray crystal
@drawcrystal

amove 0 4.5             !Draws the incoming light for the first crystal
set lwidth 0.05
rline 2 0 arrow end
rline 1 0
set lwidth 0.01

@arcdraw 3 1 90         !Draws the spherical wavelets for the o-ray 
rline 1 0
@arcdraw 6 0.5 45
rline 1 0 
@arcdraw 12 0.25 30
rline 1 0
@arcdraw 24 0.125 15
rline 2 0

set lwidth 0.05
rline 2 0 arrow end     !Draws the outgoing wave for the o-ray crystal

amove 15 0.25
@drawcrystal            !Draws the second (e-ray) crystal

amove 12 4.5            !Draws the second incoming ray
set lwidth 0.05
rline 2 0 arrow end
rline 1 0

set lstyle 2            !Draws the expected direction of propagation for an
rline 5 0               !isotropic crystal
rmove -5 0
set lstyle 1 lwidth 0.01

@ellipsedraw 1 1 70 inclination         !Draws the actual propagation 
@move inclination                       !using elliptical wavelets
@ellipsedraw 4 1 45 inclination
@move inclination
@ellipsedraw 8 0.5 40 inclination
@move inclination
@ellipsedraw 16 0.25 15 inclination
@move inclination
@move inclination

set lwidth 0.05         !Draws the outgoing ray
rline 2 0 arrow end

amove 15.5 1.25         !Adds the direction of optical axis to both crystals
rline -sin(torad(inclination)) cos(torad(inclination)) arrow end
amove 3.5 1.25
rline -sin(torad(inclination)) cos(torad(inclination)) arrow end

amove 15.6 1.25         !Adds the label to the optical axis
set just left hei 0.3
text optical axis
amove 3.6 1.25
text optical axis


set just tr

amove 2.8 4.2           !Adds labeling to the incoming and outgoing rays
begin text width 2.7
Incoming light polarised in the y direction 
end text

amove 14.8 4.2
begin text width 2.7
Incoming light polarised in the z direction
end text

amove 9.9 4.2
begin text width 1.5
o-ray (polarised)
end text

amove 21.9 4.2
begin text width 1.5
e-ray (polarised)
end text

amove 0 4.6             !Draws two axis for both the rays
@drawaxis 1
amove 12 4.6
@drawaxis 1

amove 11 0              !Separates the two crystals with a solid line
set lstyle 1 lwidth 0.1
aline 11 10

6.4 Path drawing

Within GLE we can draw a set of lines that makes up an arbitrary shape, then use the begin path and end path to define the shape and apply fill shades and line styles. The lines of code within the two commands will be stored by GLE and used to draw the entire shape at once. Commands that refer to different coordinate points will be linked by a line, for example if we were to include the code,

rline 1 0
rmove 0 1
rline 1 0
The rmove along the y-axis would be considered part of the boundary of the shape, though whether a line is actually drawn connecting the two points is left as an option for the user.

Some of the commands used in conjunction with the path drawing routine are device sensitive, they can only be guaranteed on postscript devices. Any other program may successfully interpret the postscript commands, but it is usually best to avoid drawing diagrams that are heavily dependent upon these commands.

A simple path

There is no support within GLE for drawing pie-charts; the following subroutine file, and an example of its use, can draw a pie wedge filled with any given colour.


!piesub.gle - Subroutine to draw a pie wedge between two supplied angles
sub pie ang1 ang2 radius colour$
begin path fill colour$ stroke
rmove 0 0                       !The rmove command is neccesary to set the beginning
arc radius ang1 ang2            !of the path
closepath
end path 
end sub


!drawpie.gle - Example of the use of the pie wedge routine
size 6 6 
include piesub.gle

amove 3 2
@pie 0 10 2 "grey10"
@pie 10 40 2 "grey20"
@pie 40 120 2 "blue"

A path within GLE must contain the elements begin path and end path. To the begin path command we can affix qualifiers that determine the qualities of the finished shape. In the example above the stroke command tells GLE to draw the lines that make up the shape in the currently selected line style and width. The fill command fills the ‘inside’ of the shape with the selected fill pattern, which may take the form of a text string as in the example above. What we mean by ‘inside’ the shape may seem elementary in the example above, and indeed it is, but a more formal definition, for use with complex paths, will be given in the following section. A further option, the clip command, will also be covered in the section on clipping.

The path drawn will be defined from the start of the first object drawn following the begin path command. This is not, neccessarly, the same as the initial coordinate point. In the example above the rmove 0 0 commands defines the start of the path to be at the current coordinate point, without it the start of the path would be at the beginning of the arc. The closepath commands returns to the beginnning of the shape; useful, and often necessary, when drawing complex shapes, though in the example above there is nothing to stop us completing the path manually using rmove command.

The zero winding rule

When filling complex shapes using the path commands we may often run into problems deciding which part of the shape is to be filled and which is to be left blank. GLE uses the ‘Zero winding rule’ to decide, and also provides a command that allows us to define for ourselves which the boundaries of the path.


!Zero.gle - Program to demonstrate the zero winding rule
size 18 10

sub drawbox a b         !These subroutines draw the various boxes to size.
        rline 0 b       !Because the path command does not recognise the
        rline a 0       !arrowed lines we must draw the boxes twice, once
        rline 0 -b      !for the path and once for the arrows.
        rline -a 0 
        end sub

sub antidrawbox a b 
        rline a 0 
        rline 0 b 
        rline -a 0 
        rline 0 -b 
        end sub

sub drawarrowbox a b 
        rline 0 b arrow end
        rline a 0 arrow end
        rline 0 -b arrow end
        rline -a 0 arrow end
        end sub

sub antidrawarrowbox a b 
        rline a 0 arrow end
        rline 0 b arrow end
        rline -a 0 arrow end
        rline 0 -b arrow end
        end sub

amove 1 0.5
set lwidth 0.1

begin path fill grey10          !This draws two boxes in the same direction
        @drawbox 4.5 9 
        rmove 0.5 0.5
        @drawbox 3.5 8 
        end path
@drawarrowbox 4.5 9     
rmove 0.5 0.5
@drawarrowbox 3.5 8

amove 6.5  0.5                  !This draws two boxes in opposite directions
begin path fill grey10 
        @drawbox 4.5 9 
        rmove 0.5 0.5
        @antidrawbox 3.5 8  
        end path
@drawarrowbox 4.5 9
rmove 0.5 0.5
@antidrawarrowbox 3.5 8

amove 12 0.5

begin path fill grey10          !This draws two boxes in the same direction
        @drawbox 4.5 9          !but uses the reverse command to reverse the
        rmove 0.5 0.5           !path direction
        reverse 
        @drawbox 3.5 8 
        end path
@drawarrowbox 4.5 9
rmove 0.5 0.5
@antidrawarrowbox 3.5 8

amove 0 5                       !The following adds some labels
set just cb hei 1.0 lwidth 0.05
rline 3.25 0 arrow end
rline 5.5 0 arrow end
rline 5.5 0 arrow end
rline 3.25 0 arrow end
set hei 0.5
amove 0.5 5.25
text 0
rmove 0.75 0
text 1
rmove 2 0
text 2
rmove 2 0
text 1
rmove 0.75 0
text 0
rmove 0.75 0
text 1
rmove 2 0
text 0
rmove 2 0
text 1
rmove 0.75 0
text 0
rmove 0.75 0
text 1
rmove 2 0
text 0
rmove 2 0
text 1
rmove 0.75 0
text 0

The zero winding rule is applied as follows: An imaginary line is drawn across the object. Every time a line of the path crosses the from left to right, one is added to a counter (initially set to zero); every time a line of the object crosses from right to left, one is subtracted from the same counter. Everywhere the counter is non-zero GLE assumes to be inside the object, everywhere else is considered to be outside.

When creating a complex filled shape from a path we must be aware of the direction we are drawing in. To change direction we can either deliberately draw in the opposite direction to the rest of the shape, or else use the reverse command which reverses the direction of the path of all the commands following it. The latter is useful if we wish to reuse a subroutine, as we show above.

GLE treats the commands that constitute a path as an entirely separate entity from the rest of the program. Notice that if we had not drawn the extra boxes on top of the path then there would have been no outline to the box. If we do not add a stroke qualifier to the path command then any lines that are drawn in the path will be ignored.

A problem also occurs in the use of arrow in path commands. If we specify any line or curve to begin or end with an arrow then the fill style and stroke commands will not apply, that is the path commands will fail.

Clipping

Clipping is a technique that will display only a portion of a diagram. The displayed portion being outlined using the path commands that we used in the previous section. Clipping is device sensitive and only works with postscript devices.


!Clip.gle - Demonstrates the useage of the path clip command
size 10 10              !Formats the text
set hei 4
amove 2 2
begin clip
        begin path clip
                text GLE
                amove 2 6
                box 5 2
                end path
        amove 2 2 
        for x = 0.01 to 100 step 0.005
                circle 1/x
                next x  
        end clip
amove 5 5
rline 10 10

We can draw an arbitrary clipping region by defining a closed path within the commands begin path clip and end path. We can use any arbitrary shape, but only Postscript fonts will currently work for this purpose.

The example defines a box and a line of text as the clipping region. We also draw a series of concentric circles centered on (2,2), only the areas that are defined as being within the clipped path will show through. The begin clip and end clip commands signify the end of the clipping region.

It is useful to define a clipping region when we wish to contain a set of commands to a given area. If we look at the diagram of the propagation of light in the birefringent material then, if we were producing a diagram for inclusion in a paper or thesis, it would have helped to define the crystal boundaries as a clipping region. This would have prevented the intrusion of the wavelets into the area beyond the limit of the crystal. Of course this would of added an extra layer of complexity to the program, one which we did not need at the time. It is important to balance the neatness of the clipping command with the added time taken and the lack of compatibility with non-postscript devices.

6.5 File handling

It is possible to read and write to files using GLE using various file handling commands that look rather like those used in C. fopen is used to open a file, fclose is used to close a file. This is perhaps best illustrated by an example. Imagine that you have a datafile which contains 5 columns of numbers. You want to make a new datafile with GLE that contains three columns of data (let's call them x, y and yerr) according to a particular algorithm (in this case, we ignore the first column of numbers, set x to be the second column, set y to be the quotient of the fifth and third column, and work out yerr as the error assuming that column 4 is the error for column 3, and column 6 is the error for column 5). Both the file to be read and the file to be written must be assigned a channel. In the example below, we use inchan as the channel for the input file (called "measured.dat") and outchan as the channel for the output file (called "calculated.dat").


fopen "measured.dat" inchan read
fopen "calculated.dat" outchan write

until feof(inchan)
    fread inchan a1 a2 a3 a4 a5 a6
    x=a2
    y=a5/a3
    yerr=y*sqrt((a6/a5)^2+(a4/a3)^2)
    fwriteln outchan x y yerr
next

fclose outchan
fclose inchan

This code has the desired effect and illustrates the use of the command fopen, fclose, fread, fwrite, fwriteln, feof, and the until next loop.


Next Previous Contents