DoNaLD - a Definitive Notation for Line Drawings
DoNaLD is a definitive notation for 2D line drawings. It was originally specified in Warwick Computer Science Research Report 086. A subset of the specification was first implemented by Edward Yung and subsequently modified by many other authors. The notation as it stands remains some distance away from what is specified in the research report. One of the objectives of this document is to state what is supported in the current version of DoNaLD.
Variable names and data types
Variable names
x
- refers to the variable
x
in the immediate context ~/x
- refers to the variable
x
in the context one level up /x
- refers to the variable
x
in the root (topmost) context x!
- refers to an Eden variable
- DoNaLD variables need to be declared before use.
- Eden variables (ending with !) do not need to be declared and would not be type-checked by DoNaLD. To help the type-checker, it is advisible to surround the variable with trunc() or float() to force the expression to int or real type.
pi
is a predefined constant 3.14159. It cannot be redefined as a variable associated with any context.
Data types
Type | Example |
---|---|
int | 34 |
real | 10.0 |
char | "abc" |
boolean | true, false |
point | {50, 100}, {modulo @ angle} |
line | [{10,10}, {80, 90}] |
circle | circle(centre, radius), circle({500,500}, 400) |
ellipse | ellipse(centre, major, minor) |
rectangle | rectangle({100, 100}, point1) |
image | I!ImageFile("gif", "hill.gif") |
label | label L1, L2
|
openshape | openshape cross |
within cross {
| |
shape | shape S
|
graph | func sqr { return $1 * $1; }
|
Functions
Arithmetic operators and functions
+
-
*
div
(division)mod
sqrt
(square root)log
exp
trunc
(convert real to integer)float
(convert an integer to real)rand
(random number generator)- -
int rand(int)
orreal rand(real)
if the argument is an integer, say10
,rand(10)
returns a random number ranged from0
to9
inclusive;
if the argument is a real, say1.0
,rand(1.0)
returns a random number ranged from0.0
to1.0
inclusive.
Trigonometric functions
sin
cos
tan
asin
acos
atan
- - accept only real arguments
Relational operators
&&
(and)||
(or)!
(not)<
<=
==
(equal)>
>=
Geometric functions
point midpoint(line)
- - mid-point of a line
point intersect(line, line)
- - intersection point of two lines
line perpend(point, line)
- - the perpendicular line intersecting the point
real dist(point, point)
- - distance between two points
bool intersects(line, line)
- - whether the lines intersect
bool separates(line, point, point)
- - whether the line separates the two points
bool includes(circle, point)
- - whether the point is inside the circle
bool incident(line, point)
bool incident(circle, point)
- - whether the point coincides with the path
bool pt_betwn_pts(point, point, point)
- - whether the 2nd point is within the box bounding the 1st and the 3rd point
bool colinear(point, point, point)
- - whether the points are colinear
bool distlarger(point, point, value)
bool distlarger(line, point, value)
bool distsmaller(point, point, value)
bool distsmaller(line, point, value)
- - whether the distance from the point to the point/line is larger than or smaller than the specified value
Shape transformations
trans(shape, x, y)
- - translate a shape (or openshape)
scale(shape, ratio)
- - scale a shape (or openshape) wrt the origin of the coordinate system; would not change the font size or the image size of labels
rot(shape, point, angle)
- - rotate a shape round a point by a certain angle
String functions
//
- string concatenation
itos(int)
- - integer to string conversion
rtos(real, format-string)
- - real to string conversion. format-string would be as required by the C function fprintf().
Image functions
Example:%donald real xscale, yscale xscale, yscale = 0.8, 0.8 image zoom, source source = I!ImageScale(I!ImageFile("gif", "logo.gif"), xscale, yscale) zoom = I!ImageScale(I!ImageCut(source, 20, 0, 200 * xscale, 200 * yscale), xscale, yscale) label imgzoom, imgsrc imgzoom = label(zoom, {500, 200}) imgsrc = label(source, {500, 700})The images are centred at the specified position (same for string labels). I!functionName denotes a function returning an image. This function is translated to an Eden function named as functionName. The arguments are not fully type-checked, so may sometimes cause a problem. Since this kind of function does not need to be declared beforehand, DoNaLD can easily be extended to make use of image filters chosen by the user. (See examples in $PUBLIC/lib/tkeden/scout.init.e for examples of image filters.)
Other functions
circle(center, radius)
ellipse(center, extreme_point1, extreme_point2)
rectangle(corner1, corner2)
label(string, position)
if
boolean_expressionthen
exprelse
expr.1, .2
- - 1st and 2nd points of a line or 1st and 2nd coordinate of a
point, for example:
line l l = [{0,0}, {100,100}] point p p = l.2 # i.e. {100,100} real x x = p.1 # i.e. 100
- .x, .y
- - the projection of a point onto the x- and y- axies, e.g.:
point p, q p = {100, 200} q = p.x # i.e. {100, 0}
Graphs
- A graph comprises of nSegment number of segments and nSegment + 1 number of nodes. But there may be many visualisations of the same node or segment.
- x<i> and f<i> have to be defined even though they may not be used in the node/segment definitions.
-
Both node and segment have to be defined. Should no visualisation be
associated with either node or segment, define that variable to be
[]
- Due to DoNaLD's limitations, once a variable is declared as one type, it cannot be redeclared to another type. So if the first visualisation of the node is a circle, any subsequent redefinition to the node must have the first element declared as a circle. However, you need not give any definition to it.
-
A DoNaLD graph will declare a series of node and segment entities
accessible in DoNaLD. The nodes are named as
node1_1
,node1_2
, etc. and the segments are named assegment1_0
,segment1_1
, etc., where the first number represents which visualisation of the entity and the second number is concerned with which node or segment. You can redefine the individual nodes and segments without any complaint from the system (BUG?).
Attributes
You may like to give a line or a shape a different look, by specifying a wider linewidth or a different colour. Every DoNaLD variable that can be displayed has an attribute variable (an EDEN variable) for you to modify its presentation. Integers, reals, booleans and chars have no immediate graphical representation, hence no attribute variables accompany them. Interestingly enough, openshape does not have attributes either. This is because openshape is not a shape but a collection of shapes. Its subshapes may each have an attribute but the openshape itself has not.
The attribute variables are EDEN variables, and are named after the
translated name of the DoNaLD variables in EDEN. The attribute variable
name for the DoNaLD variable Obj/line1
would be A_Obj_line1
. Attributes
are of the form:
"attr1=value1,attr2=value2..."
The set of attributes available may vary from one implementation to another. For tkeden, legal attributes are:
outlinecolor
- applicable to: any shape
acceptable values: any X-Windows recognised colour name + transparent color
- applicable to: closed shapes
acceptable values: any X-Windows recognised colour name + transparent. This is the fill colour of the shape. Note that older versions of tkeden had nooutlinecolor
-color
specified both outline and fill colours. linewidth
- applicable to:
line
,arc
,circle
,shape
acceptable values: positive integers, 0 = minimum line width linestyle
- applicable to:
line
acceptable values:dotted
,dashed
,solid
arrow
- applicable to:
line
acceptable values:first
,last
,both
,none
followed by 2 spaces) locus
- applicable to: any shape
acceptable values:true
,false
fill
- applicable to: any shape
acceptable values:solid
,hollow
Notes:
- There must not be any space character in the attribute string.
- Attributes will affect all the graphical objects within a shape. If the shape is the transformation (rotation, translation or scaling) of an openshape, the attributes given to the shape will override the attributes given to the individual shapes within the openshape.
Viewports
Viewports are workspaces where the graphical objects are placed. For the stand alone usage of DoNaLD, viewport should not be defined. Since Scout, a definitive notation for describing screen layout, has the ability to show different pictures in different (Scout) windows, when DoNaLD is used in conjunction with Scout, viewport is a useful way of separating objects into different pictures. In DoNaLD, the line:
viewport VIEW1
means that from that line onwards the graphical objects to be declared (not defined) will be associated with the viewport VIEW1. All viewports share the same conceptual space, and variables in one viewport can freely make reference to variables in other viewports. Viewports need not be displayed. Hence it is useful to dump intermediate or conceptual objects into a viewport which will not be displayed.
For backward compatibility, declaring DoNaLD variables without first
declaring a viewport will create a default viewport displaying on a
separate screen. This default viewport is named as DoNaLD
.
Comments
DoNaLD uses #
as the comment symbol. Comment starts from #
to the
end of the line.
Escape to EDEN
There are two ways of escaping from DoNaLD to EDEN.
- A line beginning with
?
will be passed to EDEN directly. Like the DoNaLD comments, this is only for one line escape. The one line escape is particularly useful for defining attributes. For example:line cable ?A_cable is "linestyle=dotted"; /* this defines the attribute of cable */ cable = ... # this is a DoNaLD definition
Not only is this escape method convenient in this case, it also gives the attribute definition a sense of close association with the DoNaLD variable.
- Switching to EDEN and back is useful if several EDEN statements are
included in a DoNaLD script.
line cable %eden A_cable is "linestyle=dotted"; /* this defines the attribute of cable */ %donald cable = ... # this is a DoNaLD definition
Bugs
- The maximum number of nested openshapes is 128.
- atan2: DOMAIN error It is a warning message only, does not affect the operation of tkeden. It occurs when the two end-points of an arc are the same.
- Eden variables in DoNaLD (identifiers ended with !) do not need to be declared and so the type checker may be confused with polymorphic operators such as arithmetic operators. In most cases, you can use trunc() or float() to force the variable to int or real.
(Note: this document was originally titled the "Quick Guide to DoNaLD".)