Luca Sepe

Posted on

# Craft beautiful geometric art using code.

Use the code basics like loops, control flow and specialized functions to generate your geometry artworks.

## Installation

### Go get

``````\$ go get -u github.com/lucasepe/g2d
``````

• MacOS
• Linux
• Windows

## How to use

To execute a local `g2d` script:

``````\$ g2d /path/to/my-script.g2d
``````

To execute a `g2d` script stored somewhere on the web:

``````\$ g2d http://my-cool-site.com/remote/path/to/my-script.g2d
``````

Use the `--directory` (or the shorter `-d`) flag to specify a destination folder for the generated PNG images.

## The `g2D` Programming Language Syntax

Example-programs can be found beneath examples/ which demonstrate these things, as well as parts of the standard-library.

### Types

g2D has the following data types: `bool`, `int`, `float`, `str`, `array`, and `fn`.

Type Syntax Notes
bool `true false`
int `0 42 1234 -5` is a signed 64-bit integer
float `0.5 4.2 1.234 -5.5` is a 64-bit double-precision floating point
str `"" "foo" "\"quotes\" and a\nline break"` are immutable arrays of bytes
array `[] [1, 2] [1, 2, 3]` grow-able arrays (use the `append()` builtin)
fn `fn(a, b) { ... }` defines a custom function

### Bindings

Variables are bounded using the `:=` operator.

``````a := 3
b := 1.2
``````

Variables may be integers, floats, strings, or arrays/hashes.

To update a variable you can simply specify the equals `=` operator:

``````a := 3    // Binding
a = a + 5 // Updating
``````

### Arithmetic operations

`g2D` supports all the basic arithmetic operation of `int` and `float` types.

``````a := 5
b := 3

c := a + b
d := c / 2
e := d * d
``````

### Builtin containers

`g2d` has one builtin containers: `array`.

#### Arrays

An array is a list which organizes items by linear sequence. Arrays can hold multiple types.

``````a := [1, 2.3, "hello!"]
b := [false, true, "Hello World", 3, 3.13]
``````

Adding to an array is done via the `push` builtin function:

``````a = append(a, "another")
``````

You can iterate over the contents of an array like so:

``````i := 0
while( i < len(a) ) {
print( "Array index ", i, " contains ", a[i], "\n")
i = i + 1
}
``````

With the definition we included that produces this output:

``````Array index 0 contains 1
Array index 1 contains 2.3
Array index 2 contains hello!
Array index 3 contains another
``````

### Functions

`g2D` uses `fn` to define a function which will be assigned to a variable for naming/invocation purposes:

``````sum := fn(a, b) { return a + b }

print(sum(5,3), "\n")       // Outputs: 8
print(sum(2.5,7.5), "\n")   // Outputs: 10
``````

Functions can be passed as values to others functions:

``````addTwo := fn(a, b, f) {
return 2 + f(a, b)
}

print(tot, "\n")            // Outputs: 71
``````

Functions inside functions

``````multiplier := fn(q) {
return fn(x) {
return x*q
}
}

multThree := multiplier(3)

print(multThree(2), "\n")  // Outputs: 6
print(multThree(3), "\n")  // Outputs: 9
print(multThree(4), "\n")  // Outputs: 12
``````

### If-else statements

`g2D` supports `if-else` statements.

``````max := fn(a, b) {
if (a > b) {
return a;
} else {
return b;
}
}

print( max(1, 2) )  // Outputs: 2
``````

### Switch Statements

`g2D` supports the `switch` and `case` expressions:

``````switch n := randi(10) {
case n % 2 == 0 {
print(n, " is even", "\n")
}
default {
print(n, " is odd", "\n")
}
}
``````

### While Loops

`g2D` supports only one looping construct, the `while` loop:

``````i := 30
while (i > 0) {
print(i, " ")
i = i - 10
}
// 30 20 10
``````

## Builtin functions

### Core

Function Description
`exit([status])` exits the program immediately with the optional status or 0
`input([prompt]` reads a line from standard input optionally printing the specified prompt
`print(...)` output a string to stdout
`printf(pattern, ...)` output a string to stdout (formatted according the specified pattern)
`sprintf(pattern, ...)` like `printf(...)` but returns a string
`bool(val)` converts value to a bool
`float(val)` converts decimal value str to float - if val is invalid returns null
`int(val)` converts decimal value str to int - if val is invalid returns null
`str(val)` returns the string representation of val
`len(iterable)` returns the length of the iterable (string or array)
`append(array, val)` returns a new array with value pushed onto the end of array

### Calculation

Function Description
`abs(x)` returns the absolute value of x
`atan(x)` returns the arc tangent, in radians, of x
`atan2(x, y)` returns the arc tangent of y/x
`cos(x)` returns the cosine of the radian argument x
`degrees(angle)` converts radians into degrees
`hypot(p, q)` returns `sqrt(p*p + q*q)`
`lerp(start, stop, amt)` calculates a number between two numbers at a specific increment
`map(v, b1, e1, b2, e2)` re-maps a number from one range to another
`max(v1....vn)` returns the largest value in a sequence of numbers
`min(v1....vn)` returns the smallest value in a sequence of numbers
`pow(x, y)` returns `x**y`, the base x exponential of y
`sin(x)` returns the sine of the radian argument x
`sqrt(x)` returns the square root of x
`radians(angle)` converts a degree measurement to its corresponding value in radians
`randf([min], [max])` returns a random float between min and max - by default min=0.0 and max=1.0
`randi([min], [max])` returns a random int between min and max

### Basic graphic functions

Function Description
`size(w,[h])` sets the size of the drawing; when both w and h are specified creates a rectangular image otherwise creates a squared one
`viewport(xMin, xMax, yMin, yMax, xOffset, yOffset)` sets up user-defined coordinate system; performs a screen reset (drawings are cleared)
`clear()` fills the entire image with the current color; clear all drawings
`fillColor(hexcolor)` sets the fill color to the specified hexcolor; example fillColor("#ff0000")
`fillColor(r, g, b, [a])` sets the fill color to r,g,b,a values - should be between 0 and 255, inclusive
`strokeColor(hexcolor)` sets the stroke color to the specified hexcolor; example strokeColor("#ff0000")
`strokeColor(r, g, b, [a])` sets the stroke color to r,g,b,a values - should be between 0 and 255, inclusive
`strokeWeight(weight)` sets the stroke thickness to the specified width
`dashes([s1, s2, ...sn])` sets the current dash pattern to use (call with zero arguments to disable dashes)
`stroke()` strokes the current path with the current stroek color and line width the path is cleared after this operation
`fill()` fills the current path with the current fill color; open subpaths are implicity closed.
The path is cleared after this operation
`fillAndStroke()` fills the current path with the current fill color and strokes it with the current stroke color; the path is cleared after this operation
`push()` saves the current state of the graphic context by pushing it onto a stack
`pop()` restores the last saved graphic context state from the stack
`snapshot([filename])` creates a PNG image with the current drawings.
If filename is omitted, it will be autogenerated with a progressive counter, that will be incremented on each
`snapshot()` invocation; this is useful if you wants to generate an animation later (using all the generated PNG images).
`xpos()` returns the current X position (if there is a current point)
`ypos()` returns the current Y position (if there is a current point)

### Graphic primitives

Function Description
`arc(x, y, r, sa, ea)` draws a circular arc centered at (x, y) with a radius of r.
The path starts at sa angle_, ends at ea angle, and travels in the direction given by anticlockwise
`circle(x, y, r)` draws a circle centered at [x, y] coordinates and with the radius r
`ellipse(x, y, rx ,ry)` draws an ellipse centered at [x, y] coordinates and with the radii rx and ry
`line(x1, y1, x2, y2)` draws a line from point (x1, y1) to point (x2, y2)
`point(x, y)` draws a point at specified coordinates (the size is equal to the stroke weight)
`quad(x1, y1, x2,y2, x3,y3, x4,y4)` draws a a four sided polygon using the provided vertices
`rect(x, y, w, h, [tl, tr, br, bl])` draws a (w x h) rectangle with upper left corner located at (x, y).
If only one radius is specified, all the corners have the same bending, if tl, tr, br, bl are specified, each corner can have a different curvature
`triangle(x1,y1, x2,y2, x3,y3)` draws a triangle using the provided vertices
`star(cx, cy, n, or, ir)` draws a star cx, cy is the center, n the number of spikes, or and ir the outer and inner radius

### Paths

Function Description
`beginPath()` starts a new path
`closePath()` adds a line segment from the current point to the beginning of the current subpath
`moveTo(x, y)` sets the begin of a new subpath starting at the specified x, y point
`lineTo(x, y)` adds a line segment to the current path starting at the current point
`arcTo(x1, y1, x2, y2, r)` adds a circular arc to the current sub-path, using the given control points and radius
`quadraticCurveTo(x1, y1, x2, y2)` adds a quadratic Bézier curve to the current sub-path; x1, y1 is the control point and x2, y2 is the end point

### Transform

Function Description
`rotate(angle, [x, y] )` updates the current matrix with a anticlockwise rotation; when x, y are specified, rotation occurs about this point, otherwise rotation occurs about the origin (angle is in radians)
`scale(sx, sy, [x, y])` updates the current matrix with sx, sy scaling factor; when x,y are specified, scaling occurs about this point, otherwise scaling occurs about origin.
`translate(x, y)` updates the current matrix with a translation to x and y
`identity()` resets the current transformation matrix to the identity matrix
`transform(x, y)` multiplies the point x, y by the current matrix, returning a transformed position

### Text

Function Description
`text(str, x, y, [ax, ay])` draws the specified text str at the specified anchor point x, y; the anchor point is x - w * ax, y - h * ay, where w, h is the size of the text (by default ax=0.5, ay=0.5 to center the text at the specified point)
`textWidth(str)` returns the rendered width of the specified text str given the current font face
`fontSize(size)` sets the font height

### Images

Function Description
`imageGet(path/to/png)` loads a PNG image from the local filesystem
`imageAt(im, x, y, [ax, ay])` draws the specified image im at the specified anchor point x, y; (ax and ay are the x and y offsets) use ax=0.5, ay=0.5 to center the image at the specified point