# The GHOUL conventions.

> The code is more what you’d call 'guidelines' than actual rules.

— Captain Hector Barbossa

## Styling of code references in this document.

Given the following function:

`AnimationFxTriangular(AnimVector=[Start,Finish,Delete],Frequency)`

Any reference to a function or module in the text will be displayed like inline code as such: `AnimationFxTriangular()`, if it is also a link, the border of the inline code block will be coloured like this: `ViewPort()`. Parameters will be displayed bold like AnimVector, and the parameter values will be displayed in italics like Start. Variables will be displayed in bold italic text, e.g. $t or CircleRadius. Whenever reference is made to the value of a variable, it will be displayed in italics, like parameter values: $t=0.1. Unless we’re in a code block of course, then it’s all dull standard-weight monospace. When I refer to a file or directory in The GHOUL, I will do so in italics: TheGHOUL/Lib/Objects/Calendar.scad.

## Admonitions

| This is a tip; there’s quite a few of these, a helpful piece of advice, or a trick to make working with The GHOUL and OpenSCAD easier.

| This is a note; quite a common occurrence, it can just be something interesting, noteworthy or otherwise deserving of a little extra attention..

| This is important; not very many things are, it’s probably something that may get overlooked but that will mess with your day…​

| This is a caution; a rare thing indeed, probably something that’s hard to troubleshoot if it goes wrong.

| This is a warning; I can’t think of many reasons to get this bad-boy out, really only justifyable if there’s risk of data loss or something soul-destroying like that.

## Directions and Angles.

The following naming convention for angles and directions is used (in comments) in The GHOUL:

Table 1. Direction naming.
Name | Meaning
--- | ---
East or 3 o’clock: | Positive X-axis, 0 degrees.
North or 12 o’clock: | Positive Y-axis, 90 degrees.
West or 9 o’clock: | Negative X-axis, 180 degrees.
South or 6 o’clock: | Negative Y-axis, 270 degrees.
Up: | Positive Z-axis.
Down: | Negative Z-axis.
Azimuth: | Angle with the positive X-axis, in the Z=0 plane, following the right hand rule.
Inclination: | Angle with the positive Z-axis.
Width: | X-dimension.
Length: | Y-dimension.
Height: | Z-dimension.

### Angles

OpenSCAD uses a right hand coordinate system, and angles in The GHOUL are expressed using the 'Right hand rule'.
Angles are expressed CCW, looking onto a plane from the positive side of the protruding axis or normal vector, i.e., angles in the Z=0 or X-Y plane are expressed CCW looking from the positive Z side with the positive X-axis being the 0 degree reference. For all other planes, the Z-axis or it’s projection is the 0 degree reference, unless a different Coordinate System is in force.

### Object orientation.

3D Objects with a directional character such as arrows or triangles are created pointing along the positive Z-axis. 2D shapes with a directional character such as arrows or triangles point along the positive X-axis.

| This convention is important in order for routines such as `position()` to have predictable results.

## Tuple, vector, array, matrix

### Element (position) references.

Whether referring to strings, tuples, arrays or matrices; every position reference is 0-indexed. Start and end positions are always inclusive.

Negative position references are counted from the end e.g. where `LeftStr(string, 3)` returns the left 4 characters (it’s 0 base), whereas `LeftStr(string, -3)` returns all but the last 3 characters of the string. Similarly, `RightStr(string, 3)` returns all but the first 3 characters, whereas `RightStr(string, -3)` returns the last 3 characters of the string. This convention allows us to trim strings or arrays without having to determine their length first.

### Type use.

In OpenSCAD, a tuple, vector,array or matrix are all essentially the same thing; arrays and arrays of arrays. however, in the GHOUL, the following 'naming convention' is maintained:

Table 2. Array structure reference.
Name | Use
--- | ---
Tuple: | A 2D or 3D vertex or a simple, short indexable variable containing different type variables like a ViewPort used by `ViewPort()`.
Vector: | Always a 2D or 3D vector in the mathematical sense.
Matrix: | Always a 2x2, 3x3 or 4x4 (homogenised) matrix as used for affine transformations.
Array | Any other indexable variable.

## Naming.

### Variable naming

Variable names are in CamelCaps.

Variables that are created inside a function or module’s namespace start with an underscore: _LocalRate.

### Function naming

Function names are in CamelCaps.

Functions that are defined inside modules or are only ever called by other functions or modules, have names starting with an underscore: `_NeverCalledDirectlyByUser()`

| These functions will NOT have any error traps since the calling function/module will have performed this task and will only make safe calls, right? Probably.

### Module naming

Module names are in CamelCaps, there is no further convention.

## Circles and `$fn`

When I first started with OpenSCAD, I found myself specifying `$fn` in `circle()` calls a lot. Most of the time, I did so because I wanted control over where the 'corners’[1] of my circles were, and I didn’t get a consistent result from OpenSCAD’s native methods—​or at least, so I thought. However, it’s pretty inefficient to have to work that way, and I’ve seen the error of my ways and rewritten (a bunch) of code to get away from that method.

But…​ I don’t like OpenSCAD’s native method of 'circle-corner-number-determination' (because I’m an awkward, controlling, stubborn sort, that’s why) so The GHOUL now uses a slightly adapted method, see TheGHOUL/Lib/Curves/Segments.scad. It does this because I want my `Arc()` corners to correspond to my `Circle()` corners, I want them to be at the same angles and locations, I don’t want horrible 'features' caused by mis-matching n-gons, I want them on the ordinal directions, and I don’t want them generated by methods I can’t control.

Is all that necessary? Perhaps not, but it bothered me, and now it doesn’t.

## Structure.

Generally, there’s no real need to worry about structure, but nested conditionals are sometimes a bit tricky. The convention adopted here isn’t the holy grail, but it seems the most 'readable' to me. Basically, it’s just my preference.

Formatting convention for nested conditionals.

    function SomeFunction(SomeParameter) =
        test 1 --------------------------------------
        ?   if_true 1 test 1-1 ----                 |
            ?   if_true 1-1       | test 1-1 range  | test 1 range
            :   if_false 1-1 ------                 |
        :   if_false 1 test 2 ---------------------------------------------
            ?   if_true 2 test 2-1 ----------------------                 |
                ?   if_true 2-1 test 2-2 --  test       |                 | test
                    ?   if_true 2-2       |  2-2        | test 2-1 range  | 2
                    :   if_false 2-2 ------  range      |                 | range
                :   if_false 2-1 ------------------------                 |
            :   if_false 2 ------------------------------------------------
        test 3 ..... &c.
        |   |   |   |- fourth (third nested) level - test 2-2
        |   |   |----- third (second nested) level - test 2-1
        |   |--------- second (first nested) level - test 1-1 and 2
        |------------- first level - test 1 and 3
    ;

## Spelling.

I usually prefer the original to a copy or derivative, that’s why I prefer my English the way the English intended it to be. OpenSCAD was written using the 'Americanised' spelling of the English language. Therefore—​with great reluctance—​when I refer to a colour, I will use the spelling 'color' to make things a little less confusing for those living between CAN and MEX. The same goes for centre and centred, I will—​despite the significant aggravation of my OCD—​conform to the OpenSCAD convention and spell them 'center' and 'centered'. There may be other examples, but none come to mind at this moment.

## Something about Geany.

I use Geany, if you do as well, life gets a WHOLE lot better if you use some of the excellent possibilities to customise Geany for OpenSCAD source-code.

Add new commands—​functions, modules and special variables ($Foo) to:

- .config/geany/tags/scad.scad.tags - for (tag) auto-completion.

- .config/geany/snippets.conf - for parameter block completion.

- .config/geany/filedefs/filetypes.OpenSCAD.conf - for highlighting.

The .config/geany/ directory can be found in your home directory. Files and directories starting with a '.' are normally hidden; type `CTRL`+`h` to make them visible in your file organiser (Linux).

| You can find more (everything) about my Geany configuration here.

If you’re still one of those who use Microsoft or Apple products, I’m afraid I can’t be of much help here; maybe you should check Linux out, it’s stable, secure and free, that’s why the majority of smart-phones, embedded operating systems, web-servers, universities and governments around the world use it…​ I bet you won’t regret it. I favour Debian but you may prefer one of it’s descendants like Ubuntu; there are a myriad of flavours to choose from.

> Linux: Without walls or fences, who needs Windows or Gates?

— unknown

1. Circles aren’t round; they’re n-gons. The GHOUL has several routines dealing with this.