2.1. Drawing in two dimensions

Note: The present chapter is a review of the process of drawing in two dimensions. Is by no means exhaustive, being limited to explain the options and point to later chapters where every method is explained in detail.

2.1.1. The canvas

In two dimensions, everything is drawn in a canvas. There is always an active canvas where the code is drawing. This active canvas can be changed: by default, the current canvas is the variable canvas that is automatically generated and included in the main scope.

The default canvas has no boundaries, thus encouraging drawing the objects with real sizes and coordinates. Later, that canvas can be scaled and placed in another canvas, if needed, or in a page to be printed, choosing scale:

rectangle r: .size 40x30 kms
maps.spain.madrid m: .place center @ r.center
page p: .size A3
place canvas @ p .scale fit
p.save image1.png .width 300px

Note that if no further drawing is needed, the same would be achieved with:

rectangle r: .size 40x30kms
save file1.png .width 300px

In which everything get scaled properly.

Further reference on canvas can be found here To learn more about canvas, look the [[canvas reference]] in [[appendix 2]]

2.1.2. Working with shapes

In Anableps, everything you paint into a canvas is called a shape. There are tens of available shapes to choose, in order to make drawing as easy as possible.

To whet you appetite, here is a (by no means exhaustive) selection of the shapes you can use. Some of this shapes will be used along the book, but you can consult the full list in the appendix 2.

Basic shapes: box, arrow, text , label, figure

Geometry: triangle, scale, 3DView

2.1.2.1. parameters of shapes

Shapes have properties that can be changed at any moment:

rectangle r: .size 20 20 20 cm .color red

here, size and color are properties of the rectangle r

The properties are not independent. Changing one can affect others or even be incompatible. For example:

circle r: .diameter 5mm .radius 4mm

The process of changing properties is not a straight-forward one, as several properties can be in conflict or the solution be difficult to find. Anableps uses an iterative method that is explained :ref:here<placement>

2.1.2.2. Colors and textures

Shapes can get colors both for filling and outlining. The outline color is set with the parameter .stroke and the filling with .fill, like the following example shows:

circle c2: .outline red .fill blue

However, some complex objects can take more than one color, in the form of two parameters:

percentBar b: .fill1 red .fill2 blue

Or, in some cases with a colorPalette:

swatch red_and_blue: .oddRow blue .evenRow white
table t: .palette red_and_blue

Colors are defined with a name (like red, blue, crimsom yellow) that can accept modifiers (darker blue, yellowish red), or a point in some color space (rgb(100,100,100), hsv(10,20,30)). For the full specification of colors, see color reference.

Textures can be used for filling (not for outlining) and work the same as colors:

triangle t: .stroke black ..width 1mm .texture spots ..color red ..size 2mm ..distance 6mm

Full reference for textures can be found at texture reference.

2.1.2.3. Materials

Any shape can accept material through the parameter .material. Alternatively, individual properties of the material can be set.

box b: .size 2 2 2 cm : .material wood

There is a list of defined materials, that can be found at the appendix 2. Materials are defined hierarchically: Wherever a node of the tree instead a branch is referred, the branch average will be used. For example, wood points to wood.average.

Here is a short version of the materials. For the full list, see appendix2.

  • Plastics: plastic, ABS, nylon6, hdpet, pet,
  • Metals: chromium, steel, stainless steel, aluminium,
  • Organic: wood, wood.oak (etc), bone, flesh,
  • Ceramic: stone, cement, concrete

2.1.2.3.1. Properties of materials

What is inside material? The following parameters configure a material:

  • density: asdfasf
  • color:
  • dielectric: dielectric constant
  • conductivity:
  • permeability: magnetic permeability

Note: In 2 dimensions, all volumetric properties assume a value of 1m for the third coordinate, so any intensive property stays the same. This can be changed altering the parameter .thickness.

These properties are used by operators or simulations. Additionally, the user can specify other properties using the parameter xtra inside a material:

box b: .size 2 2 2 cm: .material wood ..xtra spicyness 2

2.1.2.3.2. Default material

If no material is specified, default has the following properties:

  • density: 1.0
  • color: white
  • dielectric: same as vacuum
  • conductivity: 0
  • permeability: same as vacuum

2.1.3. Putting Text in canvases

Placing texts in the canvas is a fundamental part of drawing sketches. Anableps strives to give as much flexibility as possible. Font, size and aspect can be changed:

Example of fonts bolds, and sizes

The guideline can be straight or curved:

example of curved text

The text can be placed and queries about the size are allowed too:

example of placing center and size queries

Full text reference can be found here

2.1.3.1. Formulas

Formulas how??

2.1.4. Placing the shapes

Something fundamental to create a drawing is to place the shapes in the desired positions. There are three fundamental ways to move every object in the desired place.

Being a language to produce graphics comes with several advantages and disadvantages, so Anableps provide options at three different level of the axis scripting-gui. Those are:

  • matings. Using the command place in the code. Place uses constraints to place the object as it is wanted in relation with other objects. Constraints are of the kind of parallel, angle, tangent, etc. This is useful for quick scripting and geometrical drawings.
  • Layout placement: This is usually used in combination with script placement, or could be used as a first rough step. A text block with points and numbers serves as a template for placing the shapes around.
  • interactive placement: Being Anableps a mixture between a language and a GUI, the user can always invoke the .interactive function of any object to open a GUI to place it. After closed, that GUI will inject the code needed for the desired changes. This results sometimes in more verbose code but, depending on the users, interactive placement can be seen as just a tool to refine the script, or being the only used method to place objects.

The .interactive option can be used on every object in anableps. It’s worth try

(image with the screen and user placing something)

By the way, the same applies for 3D placement [1] . 3D drawing and placement is slightly more complex and will be thoroughly explained in [[chapter 3]]

2.1.4.1. Mate placement

Command placement is a setting of rules to place an object. Let’s see an example:

circle c: .radius 40cm
line l: .from 0 0 .to 40 40
place l.p1 @ c.center , l.p2 @ c.border

The command place takes on object as an argument. Following the colon, constraints are listed:

  • Each constraint takes an attribute of the object
  • Only objects listed in the left of any placement will be moved. Those at the right half are left as static.

2.1.4.2. An useful object. Layout:

In two dimensions, is very helpful use layouts. A layout is a text-block that visually defines where some objects should go. They are suited to lay out the positions of the main objects of a drawing. Let’s see an example:

# Example 3.1 a graph

# 1) create a layout
layout l: <<
                 .C

         .A              .B

                .D
>> .cellSize 2x2 cm

box b1: .size 20 10 .place center@l.A
box b2, b3, b4: .as b1
place {
    b1.center @ l.A
    b2.center @ l.B
    b3.center @ l.C
    b4.center @ l.D
}
# place {b1,b2,b3,b4}: .center @ {l.A, l.B, l.C, l.D}

# 2) now, we can add the frills to the drawing

arrow a1: .from b1.right .to b2.left
arrow a2: .from b1.down .to b3.top

Layouts are easy to see and to change, helping to solve the inherent lack of expressivity of the scripts.

Layouts can be stitched together::
l1 = layout … l2 = layout … l3 = l1 + l2 # glues them horizontally

And recursively defined:

l1 = layout ...
l2 = layout ...
l3 = layout <<

    <l1>           <l2>

>>

For a full explanation of layouts, see [[layouts]]

2.1.4.2.1. Using the GUI

Being a script language to produce graphics harbours inherent limitations. Placing some point with the mouse is immediate and needs no thinking at all. Placing with commands is sometimes cumbersome. How can we get the best of the two approaches? Allowing graphical input.

But graphical interfaces mix badly with code

What to do? give the programmer the possibility of opening a gui at any point of the code to solve that placement problem he needs, or to check if the script is doing what is supposed to do

The GUI produces code, so although there is a general GUI for just “placing objects around”, each object has a function interactive that opens a GUI for defining that object.

Say, we want to make a curve. Then we create a curve and…:

curve c: .points <interactive>
When the code comes here, it opens a GUI with the current canvas state, and prompts the user to enter
the points that make the curve.

2.1.5. Layers

Each canvas contains infinite layers, defined with a number. Layers start at 1, closer to the viewer and increase moving away, so objects in layers with small index shadow those in larger layer indexes.

Individual objects can be placed in one or another layer using .layer:

box c: .size 10x20mm .layer 3

If nothing specified, objects are laid by default on the canvas.activeLayer which defaults to 1. this, of course, can be changed:

box b: size 20x20cm
canvas.setLayer 2
# equivalent to canvas.activeLayer = 2
box c: size 20x20cm
place c.center @ b.right
# c is shown behind b.

To improve readability, layers can be named:

canvas.nameLayer 2 "myLayer"
canvas.setLayer myLayer
canvas.segment .from 10 10 .to 20 20

Note that myLayer is just a string. If you want to access to that layer, use canvas.layer[myLayer], that returns a layer object.

Layers have attributes that affect their visibility:

  • hidden:
  • transparency:
  • groups: groups this layer belongs to

2.1.5.1. The silk layers

Sometimes, when we include labels, and annotations and the like, we want those features to have a size according with the output canvas where they are displayed, no matter in which canvas are drawn.

Usually there is only need for one silk layer, but more silk layers can be defined

2.1.6. Using several canvases

For any drawing other than the basic ones, its useful to use several canvases and place them toghether

Each object is a canvas Canvas are placed inside other canvases There are canvases

viñetas, etc

2.1.7. Advanced properties of canvases

2.1.7.1. Forces

Shapes in canvases can be used to be moved away or deformed using forces. Anableps comes with two forces preconfigured (gravity and electromagnetism), but other forces can be set up and displayed.

Forces can move objects around, deform some plastic objects. Forces on objects can be displayed as well as fields.

../_images/forces-1.png

some examples of forces and fields around shapes

2.1.7.1.1. Gravity

Objects in a canvas can be affected by gravity and other fields. To do that, first, the gravity must be enabled with:

canvas.gravity = 9.8 m/s2

or any other quantity. Additionally, gravity must have either a direction, a center, or set to @auto asdf

((Examples of it: ))

There can be an medium (like an atmosphere), too, in which the objects reside, given by the object canvas.medium:

canvas.medium = air

that will be taken from the material database, or defining it straight away:

canvas.medium = medium .viscosity 10cP .density 1g/cm3

Once this is set, objects will feel a force on themselves, that’s all. Unless time is passing, however, they will not move. Force can be queried and displayed, as well as the original fields:

canvas: .size: 40 40 cm : .gravity @auto # we set the size of the default canvas to 40x40cms
circle {c,d}: .at {10 10, 20 20} .radius {5, 6} # two circles at 10 10 and 20 20
magicPaper p: .sense gravity .display isolines .layer 2   # barocromic paper!
canvas.display: .width 400

There is an exception, however. Some bodies like ropes, cables and chains, use the gravity force to configure themselves, even if time is not passing by:

canvas: .size: 40x80 cm : .border 1px, black
triangle {a,b}: .base 5 : .height 30 : .place top @ {(10,60), (50,60)}}
cable c: .lenght 100 : .from a.top : .to b.top
label l {
    .text "max. tension on the cable {c.strain(0.5):2.2}.blue distance {distance(c, line(0,0,10,0))}.green"
    .place center @above c : font.size 10px
    }
canvas.display: .width 400
../_images/forces-chain.png

In the above example, gravity deforms chains even if time doesn’t advance.

A next step would be to move the objects according to that forces they feel by being in. This will be thoroughly explained in the chapter Simulations. Here is a brief introduction.

Todo

explain a brief simulations

2.1.7.1.2. Electromagnetism

Just as with gravity, objects can create, deform and feel both electrical and magnetic fields:

canvas: .size: 40 40 cm : .emf @auto # we set the size of the default canvas to 40x40cms
circle {c,d}: .at {10 10, 20 20} .radius {5, 6} .charge {5V, -5V} # two circles at 10 10 and 20 20
magicPaper p: .sense potential .display isolines .layer 2   # barocromic paper!
canvas.display: .width 400

For magnetic fields:

canvas: .size: 40 40 cm : .emf @auto # we set the size of the default canvas to 40x40cms
circle {c,d}: .at {10 10, 20 20} .radius {5, 6} .charge {5V, -5V} # two circles at 10 10 and 20 20
magicPaper p: .sense potential .display isolines .layer 2   # barocromic paper!
canvas.display: .width 400

2.1.7.1.3. Other forces

There can be other fields, too.


[1](although the layout system is not so powerful in three-dimensions as it is here)