In 1994 I was working for company “ALS” to develop driving theory test program. The main problem was to prepare program questionnaire that reached 500 questions, most of them contained graphics.
To do that I invented a simple programming language to deal with 2D graphics objects such as:
- lines,
- rectangles,
- polygons,
- circles,
- ellipses,
- etc
One of the most important construction of language is geometric transformation. Language supports: reflections, rotation, translation, scaling transformation. User may use transformations in very natural way, for example:
TRANSLATE (45,30)
{
REFLECTY()
{
ROTATE (45)
POLYGON (7,-15,70,-15,-70,-40,-70,0,-140,40,-70,15,-70,15,70)
}
}
This means:
- rotate polygon to 45 degrees
- apply reflection transformation for rotated polygon
- translate it 45 pixels up and 30 right
Presented here language lets encode once complex enough planar graphic object such as road signs or symbolic car image and after that use it in other images applying transformations. I implemented language parser that converted source code to byte-code and engine to execute byte-code. Important to note that this approach let me do very compact questionnaire – it was very significant in the 1994.
The main constructions of language are as follows:
Geometric Primitives
|
Geometric primitive
|
Explanation
|
| PIXEL(X1,Y1) |
Point |
| SEGMENT(X1,Y1,X2,Y2) |
Straight segment |
| POLYLINE(X1,Y1,X2,Y2,...Xn,Yn) |
Sequence of connected straight segments |
| POLYGON(X1,Y1,X2,Y2,...Xn,Yn) |
Closed sequence of connected straight segments |
| RECTANGLE(X1,Y1,X2,Y2) |
Rectangle |
| FRECT(X1,Y1,X2,Y2) |
Filled rectangle |
| TRIANGLE(X1,Y1,X2,Y2,X3,Y3) |
Triangle |
| CIRCLE(Xc,Yc,R) |
Circle |
| FCIRCLE(Xc,Yc,R) |
Filled circle |
| ELLIPSE(Xc,Yc,Rx,Ry) |
Ellipse |
| FELLIPSE(Xc,Yc,Rx,Ry) |
Filled ellipse |
| ARC(Xc,Yc,Fi1,Fi2,R) |
Arc |
| PIESLICE(Xc,Yc,Fi1,Fi2,R) |
Pie slice |
| SECTOR(Xc,Yc,Fi1,Fi2,Rx,Ry) |
Sector |
| OUTTEXTXY(X,Y,Literal) |
Displays text line at (X,Y) |
| OUTTEXTXY(X,Y,Filename) |
Displays text from file at (X,Y) |
| TEXTRECT(X1,Y1,X2,Y2,Literal) |
Displays text in rectangle |
| TEXTCENTER(Y,Literal) |
Displays horizontally centered text line |
Graphic settings commands
|
Graphics setting command
|
Explanation
|
| COLOR(color) |
Set pen color |
| FILLSTYLE(style,color) |
Set fill pattern and color |
| LINESTYLE(style,width) |
Set line style and width |
| FONT(fontname) |
Set font |
Planar Transformations
|
Transformation
|
Explanation
|
| TRANSLATE(dX,dY) |
Translation operation: (X,Y) -> (X+dX,Y+dY) |
| SCALE(COEFF) |
Scaling. Is performed in 4 steps:
- Computation of geometric object centre of mass (Xc,Yc)
- Translation of object to (0,0). In other words we do TRANSLATE(-Xc,-Yc). So after that object’s center of mass is moved to (0,0).
- For each point of object (X,Y) perform multiplication: (X,Y) -> (X*COEFF,Y*COEFF)
- Move object to the old place: TRANSLATE(Xc,Yc)
|
| STRETCHX(COEFF) |
Scaling that affects only X-coordinates of object |
| STRETCHY(COEFF) |
Scaling that affects only Y-coordinates of object |
| REFLECTX |
(X,Y) -> (X,-Y) |
| REFLECTY |
(X,Y) -> (-X,Y) |
| TRANSPON |
(X,Y) -> (Y,X) |
| ROTATE(ANGLE) |
FI=(ANGLE/180)*PI
(X,Y) -> (X*COS(FI)-Y*SIN(FI),X*SIN(FI)+Y*COS(FI)) |
Examples of Geometric Language
|
Object view
|
Object program in Geometric Language
|
 |
#include "TRIS.PIC"
COLOR (BLACK)
FILLSTYLE (SOLID_FILL,BLACK)
//
// BUDKA
//
TRANSLATE (45,2) {
FRECT (-20,-30,20,30)
// WINDOW
COLOR (WHITE)
FILLSTYLE (SOLID_FILL,WHITE)
TRANSLATE (0,-10)
FRECT (-10,-10,10,10)
COLOR (BLACK)
FILLSTYLE (SOLID_FILL,BLACK)
// KRYSHA
TRANSLATE (2,-25)
FRECT (-22,-5,22,5)
}
// KOTEL
TRANSLATE (-30,13) {
POLYGON (7,-50,0,50,0,50,-20,-40,-20,-45,-15,-48,-10,-49,-5)
REFLECTX ()
POLYGON (7,-50,0,50,0,50,-20,-40,-20,-45,-15,-48,-10,-49,-5)
}
// Chimney
TRANSLATE (-55,-17)
FRECT (-7,-10,7,10)
// FUNDAMENT
TRANSLATE (-5,45)
FRECT (-72,-10,72,10)
// BUMPER
TRANSLATE (-75,50)
FRECT (-10,-10,10,10)
// Wheels
TRANSLATE (-50,55) {
COLOR (BLACK)
FILLSTYLE (SOLID_FILL,BLACK)
FILLCIRCLE (0,0,15)
COLOR(WHITE)
FILLSTYLE (SOLID_FILL,WHITE)
FILLCIRCLE (0,0,12)
}
TRANSLATE (-10,55) {
COLOR (BLACK)
FILLSTYLE (SOLID_FILL,BLACK)
FILLCIRCLE (0,0,15)
COLOR(WHITE)
FILLSTYLE (SOLID_FILL,WHITE)
FILLCIRCLE (0,0,12)
}
TRANSLATE (30,55) {
COLOR (BLACK)
FILLSTYLE (SOLID_FILL,BLACK)
FILLCIRCLE (0,0,15)
COLOR(WHITE)
FILLSTYLE (SOLID_FILL,WHITE)
FILLCIRCLE (0,0,12)
}
// DISKS
TRANSLATE (-50,55) {
COLOR (BLACK)
FILLSTYLE (SOLID_FILL,BLACK)
FILLCIRCLE (0,0,5)
COLOR (WHITE)
FILLSTYLE (SOLID_FILL,WHITE)
FILLCIRCLE (0,0,2)
}
TRANSLATE (-10,55) {
COLOR (BLACK)
FILLSTYLE (SOLID_FILL,BLACK)
FILLCIRCLE (0,0,5)
COLOR (WHITE)
FILLSTYLE (SOLID_FILL,WHITE)
FILLCIRCLE (0,0,2)
}
//
// SMOKE
//
COLOR (BLACK)
FILLSTYLE (SOLID_FILL,BLACK)
TRANSLATE (0,-115)
FILLCIRCLE (0,0,12)
TRANSLATE (0,-90)
FILLCIRCLE (0,0,20)
TRANSLATE (-20,-70)
FILLCIRCLE (0,0,16)
TRANSLATE (-55,-30)
PIESLICE (0,0,0,180,6)
TRANSLATE (-50,-40)
FILLCIRCLE (0,0,6)
TRANSLATE (-40,-45 )
FILLCIRCLE (0,0,8)
TRANSLATE (-30,-50 )
FILLCIRCLE (0,0,10)
TRANSLATE (-25,-55)
FILLCIRCLE (0,0,10)
TRANSLATE (-30,-60 )
FILLCIRCLE (0,0,10)
|
 |
#include "COLORS.DEF"
FILLSTYLE (SOLID_FILL,DARKGRAY)
//COLOR (WHITE)
TRANSLATE (100,120) {
SCALE (2,5) {
#include "102.PIC"
}
}
TRANSLATE (260,120) {
SCALE (2,5) {
#include "106.PIC"
}
}
TRANSLATE (420,120) {
SCALE (2,5) {
#include "122.PIC"
}
}
TRANSLATE (100,260) {
SCALE (2,5) {
#include "204.PIC"
}
}
TRANSLATE (260,260) {
SCALE (2,5) {
#include "205.PIC"
}
}
TRANSLATE (420,260) {
SCALE (2,5) {
#include "206.PIC"
}
}
// Draudziamieji zenklai
TRANSLATE (100,400) {
SCALE (2,5) {
#include "318.PIC"
}
}
TRANSLATE (260,400) {
SCALE (2,5) {
#include "322.PIC"
}
}
TRANSLATE (420,400) {
SCALE (2,5) {
#include "335.PIC"
}
}
|
Other examples of images implemented in Geometric Language
 |
 |
|