To support OpenGL drawing and make it much easier than plain OpenGL, there is a 3D turtle graphics, also called ``dragon graphics''. The basic principle of turtle graphics is the ``turtle'', a directed point in the coordinate space that can move around and leaves a trail on its way.

For 2D turtle graphics, there are not much settings to choose. You can set the color and the width of the line you stroke, or choose to fill your path, but that's it. 3D objects have much more aspects than simple lines or flat surfaces. Therefore, a 3D turtle graphics demands other features to define the trail it leaves.

First, the turtle flies through space, and is therefore called ``dragon''. This increases the degree of freedom - a 2D turtle can only turn left or right, a 3D dragon can turn left, right, up, and down. Additionally, it can roll to the left or right.

Then you have to define the vertex points of your trail yourself. You can define points around the current position of the dragon, which are connected to points around the previous stop of the dragon. These rounds around the dragon are knit together, forming the ``trail'' of the dragon. You can add or drop vertex points, but if you drop point, make sure that they are at least on a straight line (or better all on the same location).

There are several groups of operation, let's start with the navigation of the dragon. The angles used are radians by default.

**left**( f -- ) turns the dragon's head left**right**( f -- ) turns the dragon's head right**up**( f -- ) turns the dragon's head up**down**( f -- ) turns the dragon's head down**roll-left**( f -- ) rolls the dragon's head left**roll-right**( f -- ) rolls the dragon's head right**x-left**( f -- ) rotate the dragon left around the x axis**x-right**( f -- ) rotate the dragon right around the x axis**y-left**( f -- ) rotate the dragon left around the y axis**y-right**( f -- ) rotate the dragon right around the y axis**z-left**( f -- ) rotate the dragon left around the z axis**z-right**( f -- ) rotate the dragon right around the z axis**forward**( f -- ) move the dragon in z direction**forward-xyz**( fx fy fz -- ) move the dragon**degrees**( f -- ) steps per circle. Common cases: 2pi for radians, 360 for deg, 64 for asian degrees, or whatever you find suits your application best.**scale**( f -- ) scales the dragon's step width by the factor f**scale-xyz**( fx fy fz -- ) scale the dragon's step width in x, y, and z direction**flip-clock**( -- ) change default coordinate from left hand to right or the other way round. Use that after scale-xyz with an odd number of negative scale factors.

There are some functions to save and restore the turtle's state, and to use the turtle matrix stack for matrix multiplications, so that you can create arbitrary synthetic transformations with one step.

**>matrix**( -- ) push turtle matrix on the matrix stack**matrix>**( -- ) pop turtle matrix from the matrix stack**matrix@**( -- ) copy turtle matrix from the stack**1matrix**( -- ) initialize turtle state with the identity matrix**matrix***( -- ) multiply current transformation matrix with the one on the top of the matrix stack (and pop that one)**clone**( -- o ) create a clone of the turtle**>turtle**( -- ) clone the turtle and use it as current object**turtle>**( -- ) destroy current turtle and pop previos incarnation

Then there are the operations to create pathes. A path is partitioned in ``rounds'', where each point in one round is connected to the corresponding point in the previous round. Rounds can add points or drop points from the previous round (dropped points are not connected, and therefore should be at least in a line with those points that are connected). The first round in a path has to be defined immediately after open-path, the other rounds must be enclosed in open-round and close-round.

**open-path**( n -- ) opens a path with n points in the first round**close-path**( -- ) closes a path and performs the final rendering action**next-round**( -- ) closes a round and opens the next one**open-round**( n -- ) opens a round with n points (obsolete)**close-round**( -- ) closes a round (by copying the first point as last point) and performs the per-round rendering action (obsolete)**finish-round**( -- ) performs the per-round rendering action without closing the round first (this is for open objects) (obsolete)**add-xyz**( fx fy fz -- ) adds the point at the x,y,z-coordinates relative to the turtle. x is up from the turtle, y right, z before. The point is connected to the same point of the previous round as the point before.**set-xyz**( fx fy fz -- ) sets a point with x,y,z-coordinates. The point is connected to the next point of the previous round as the point before.**drop-point**( -- ) skips one point, set-xyz is equal to add-xyz drop-point**set-rpz**( fr fphi fz -- ) set with cylinder coordinates**set-xy**( fx fy -- ) set-xyz with z=0**set-rp**( fr fphi -- ) set with cylinder coordinates, z=0**set-r**( fr -- ) set with cylinder coordinates, z=0, phi=current_phi, current_phi+=dphi**set**( -- ) set at current dragon location**add-rpz**( fr fphi fz -- ) add with cylinder coordinates**add-xy**( fx fy -- ) add-xyz with z=0**add-rp**( fr fphi -- ) add with cylinder coordinates, z=0**add-r**( fr -- ) add with cylinder coordinates, z=0, phi=current_phi, current_phi+=dphi**add**( -- ) add at current dragon location**set-dphi**( fdphi -- ) sets dphi

The turtle graphics supports several drawing modes: points, wire-frame, solid, and textured.

**points**( -- ) draw only vertex points**lines**( -- ) draw a wire frame**triangles**( -- ) draw solid triangles**textured**( -- ) draw textured triangles**smooth**( -- ) variable: set on for smooth normals when rendering textured, set off for non-smooth rendering**xy-texture**( -- ) texture mapping based on x and y coordinates**zphi-texture**( -- ) texture mapping based on z and phi coordinates**rphi-texture**( -- ) texture mapping based on r and phi coordinates**zp-texture**( -- ) texture mapping based on z and the point number coordinates**load-texture**( addr u -- t ) loads a ppm file with the name**addr u**and returns the texture index**t****set-light**( par1..4 par n -- ) Set light source n

The SQL interface allows to interface with a database using the structured query language SQL. It now has only an interface to PostgreSQL, because noone wrote one to other databases.

The database interface has a simple foundation. You can send an SQL query string and get the result back as a table.

**database new**( addr u -- ) opens the database specified by name**exec**( addr u -- ) the query string**fields**( -- n ) the number of fields per result**tuples**( -- n ) the number of tuples (results)**field@**( i -- addr u ) obtains the field name**tuple@**( i j -- addr u ) obtains a tuple entry**clear**( -- ) clears the result buffer

There are also some output functions to display the result of a query or to create a table containing the entries

**.heads**( -- ) displays the field names**.entry**( i -- ) displays an entry line**.entries**( -- ) displays all results including names**entry-box**( -- o ) creates a MINOS object with the query results

A set of methods facilitates the creations of new tables

**create(**( addr u -- ) starts creation of a named table**:string**( addr u n -- ) a`varchar`array with n chars max**:int**( addr u -- ) an integer**:float**( addr u -- ) a floating point number**:date**( addr u -- ) a date**:time**( addr u -- ) a time**inherits**( addr u -- ) inherit mechanism of PostgreSQL, must be last (there may be multiple inherits statements)**)**( -- ) ends the creation o a table**drop**( addr u -- ) drops a table

There are also ways to construct a query string

**select**( addr u -- ) starts a select query, the argument is the selection; there can be several selections per query**select-distinct**( addr u -- ) starts a select distinct query**select-as**( addr1 u1 addr2 u2 -- ) argument 1 is the selection, argument 2 is the name it is assigned to**from**( addr u -- ) specifies the table(s) to select from**where**( addr u -- ) specify where clauses (several combined with AND)**group**( addr u -- ) grouped by argument**order**( addr u -- ) specifies the ordering argument**order-using**( addr u -- ) specifies order and ordering operation

Bernd Paysan, 09feb1999, 04apr1999