Introduction

Geo-AID is a tool to generate figures based off of rules given in the script file. Its main purpose is to minimize the pain related to drawing figures for certain mathematical problems or theorems. It's currently in the early development.

Note: Geo-AID is not designed to produce perfect output. It is designed to produce best output. This means that it might sacrifice partial accuracy in favor of better readability. It may also make other compromises and produce unexpected results at times. If you're having trouble with this kind of behavior, visit Dealing with complicated figures

As an entry point, Geo-AID uses GeoScript - a language used to describe a figure. Aside from that, special parameters can be set as command line arguments. This book is meant to serve as a guide to anyone starting to use Geo-AID and as a reference to anyone who wants to know more.

Note: This book is held up-do-date with the latest released version on crates.io.

How does Geo-AID work?

First, the input script is compiled into a series of rules and definitions. All type-checking happens here. Geo-AID will also try to apply certain optimizations, if possible. Then, the compiled rules are fed to the generator. The generator itself consists of two core parts - the "Magic Box" (which got its name when Geo-AID was just an idea on a piece of paper) and the critic. The image data (point locations etc.) is then generated over tens of thousands of generation cycles. A single cycle consists the following steps:

  • The current version of the data passes through the Magic Box, which adjusts the points/reals (adjustables) by a random vector based on the adjustable's quality.
  • The adjusted data is then rated by the critic, which checks how well the new figure meets the given requirements (rules) and gives each adjustable a score in 0-1 range.
  • If the new data is considered better than the previous one, it replaces the current version. Otherwise it gets discarder.

The above cycle runs for each of the 512 (by default) threads and after each cycle a new version gets chosen (or all new versions get discarded). The generation process lasts until a certain requirement is met, e. g. the average overall figure quality increase over the last few thousands of cycles does not exceed a certain value.

After an image is generated, the data goes to the projector, which designs how it should be rendered and passed on to the selected renderer, which creates the final output.

Beginner guide

This guide will get you through your first steps with Geo-AID. You will install the tool (if you haven't already) and create your first figure. Then, you will learn how to deal with figures that require distances and how to use Geo-AID parameters to your advantage.

Getting started

Installation

Before you start using Geo-AID, you'll need to install it. Unfortunately, it does not come in the form of precompiled binaries and you'll need some other tools to build it. First, install Rust and Cargo. Once you're done, there are two ways of setting up Geo-AID:

The first way is to simply use the cargo install method:

cargo install geo-aid

This has the advantage of installing Geo-AID globally, so that you can run it from anywhere. It will take care of all dependencies for you. Building may take some time, but once it's done, it's done for good (unless you'll want to update it).

The second way is to clone/download the GitHub repository (remember to get the last vX.X version) and build Geo-AID yourself. In this, case, you will also need the geo_aid_derive source. To download the repos, you'll need to download the .zip file and unpack it somewhere. If you want to clone it (recommended), you'll need git. The clone way is shown below

mkdir geo-aid
cd geo-aid
git clone https://github.com/DragonGamesStudios/Geo-AID.git
git clone https://github.com/DragonGamesStudios/geo_aid_derive.git
cd Geo-AID
git checkout v0.2

It's important that if you compile from source, you should preserve this file structure:

| some_folder:
    | geo-aid
    | geo_aid_derive

Then, either build it with cargo build --release and use the produced executable or run it with cargo run --release -- <geo-aid arguments here>.

Run the program with the --version flag to check if it works properly. You can also run geo-aid --help (replace geo-aid with cargo run --release -- if using the second way) if you want to see how to use the tool CLI (you can also check the CLI reference).

The rest of this book will assume you have the command globally available (as if it was installed).

Your first figure

In order to use Geo-AID, we have to tell it exactly what we want. We can do this with a script file. Geo-AID uses a special language called GeoScript that lets us give specific instructions. Create the following file with a name of your choice, say figure.geo:

let A = Point();
let B = Point();
let C = Point();

AB = AC;
AB = BC;

and run it with the following command:

geo-aid figure.geo figure.svg

After a short wait a new file figure.svg should show up. Open it in any SVG previewer (could even be your browser) and gaze at your first figure in awe:

An equilateral triangle ABC

Ok, but what exactly happened here? Let's take a closer look at the script we've just given to Geo-AID:

First, we have the three let statements. These statements are used to create variables. In our case, these variables are points created with the Point() function. You can also add special display parameters to the variable definitions to change how they are rendered. For example, if you change the first line to the following:

let A [label = G] = Point();

you should get something like this:

An equilateral triangle BCG

After the variable definitions, we have the two lines:

AB = AC;
AB = BC;

These are called rule statements. They represent a relationship between the left hand side and the right hand side. In this case, the relationship is the equality of lengths AB, BC and AC. It's worth noting that the equality sign represents a rule, not a definition or a redefinition. GeoScript is a description language, not a programming one.

Geo-AID takes these requirements and attempts to create a figure that meets them.

let statements and rules can be sometimes combined by adding rules after the left hand side of a let statement. For example:

# This is a comment
let A = Point();
let B = Point();
let C = Point();
let r = BC < AB;

let omega = Circle(A, r);

Here, r is set to the distance BC and said to be smaller than AB.

Expressions

Geo-AID mostly operates on expressions. They are variable definitions and both sides of rules. Expressions can be mathematical operations, function calls, lines, distances and literals. All expressions produce values of certain types. These can be divided into the following categories:

  • primitives
  • point collections
  • bundle types

Primitives are points, lines, circles and scalars. They're what the generator operates on and what everything is ultimately compiled into. Everything else is just an abstraction over these primitives. Additionally, scalars can have units. Performing addition or subtraction on scalars with incompatible units is an error.

Point collections are sequences of point letters, like AB, ABC, GFED, X, A'V. For a name to be collectable, it has to be a single, uppercase letter with an arbitrary number of ticks (') following it, that represents a point. Point collections can also be constructed using &(...) syntax. You can use them on the left-hand side of let statements to unpack the rhs expression onto a point collection. Note, however, that not all types have that option.

let ABC = &(intersection(XY, GH), mid(G, H), intersection(TU, KL));

Bundle types are essentially like structs in programming languages. They have their primitive fields and functions defined on them that can be used for more comfortable workflow.

Implicit conversions

Geo-AID is capable of performing some implicit conversions:

  • Unknown-unit scalars (usually literals) can be converted into a scalar with a distance unit.
  • A point collection consisting of two points can be converted into a line or the distance between the two points, depending on the context.
  • A point collection of length one is always automatically converted into a point.
  • When performing mutliplication/division over a scalar with a unit and a scalar with an unknwon unit, the latter is automatically converted into a unitless scalar (standard scalar in mathematics).
  • Any variable defined with an unknown-unit scalar is assumed to be unitless.

Shortening the code with iterators

Many figures feature multiple points and defining each one with a separate let statement can feel very verbose. To help that, GeoScript has a powerful iterator system. Iterators can be used in let statements and rules on both sides. A sequence of expressions separated by a comma is called an implicit iterator. Using these, we can collapse multiple lines of a script into a single one. For example, our first figure script becomes the following:

let A, B, C = Point();

AB = AC, BC;

Iterators are expanded into multiple rules/statement by simply iterating over the given sequence. Note that implicit iterators take precedence over binary arithmetic operators. Here's a few examples:

AB, BC = CD, EF;

# Becomes
AB = CD;
BC = EF;
AB < XY + YZ, OI;

# Becomes.
AB < XY + YZ;
AB < XY + OI;

whereas

AB < (XY + YZ), OI;

# Becomes

AB < XY + YZ;
AB < OI;

To use implicit iterators inside a function call, simply put parentheses around them: intersection(AB, (KL, XY))

Another type of an iterator is an explicit iterator. These are written in the following way:

AB = $1(AC, BC);

The above example is equivalent to just writing

AB = AC, BC;

The number after the dollar sign is the id of the iterator. If you're using a single id, they function just like implicit iterators. However, when using multiple different ids, you can get some interesting results:

$1(AB, CD) < $2(XY, YZ);

# Becomes
AB < XY;
CD < XY;
AB < YZ;
CD < YZ;

Explicit iterators can also be nested, allowing for even more complicated rules. For example:

$1(AB, BC) > $1(x, $2(a, b)), $3(9, 4, 3);

# Becomes
AB > x;
BC > a;
BC > b;
AB > 9;
AB > 4;
AB > 3;
BC > 9;
BC > 4;
BC > 3;

There are a few important things to remember about iterators:

  • implicit iterators have a default id of 0,
  • let statements only accept implicit iterators on their left hand side,
  • let statements only accept one level of iteration in their defining expressions,
  • all iterators of the same id must have the same length.

Exact rules regarding the iterators can be found here.

Working with distances

NOTE: EVERYTHING REGARDING THIS CHAPTER IS VERY LIKELY TO CHANGE IN THE COMING UPDATES.

If we run the following code in Geo-AID:

let A, B, C = Point();

AB, BC, AC = 1, 2, 3;

We'll get the following compiler error:

error: you must set a value for flag `distance_literals`.
 --> test.geo:3:14
  |
3 | AB, BC, AC = 1, 2, 3;
  |              ^ note: Required because of this line.
  |              ^ help: possible values: `adjust`, `solve`
Fix: Consider defining this flag at the top of the file.
 --> test.geo:1:1
  |
1 | @distance_literals: adjust;
  | +++++++++++++++++++++++++++
  | let A, B, C = Point();

Why is that?

Geo-AID operates on its own coordinate system and has to accept figures with lengths specified in thousands, as well as lengths specified in numbers lower than 1. Because of this, distance literals have to be treated in a special way. Geo-AID handles them by creating a special variable representing a distance unit. This variable then mutliplies every distance literal. For that to work, the compiler has to be informed that you are aware of using distance literals by adding a flag.

Flags

Flags can modify the behavior of the generator. They are grouped in categories and can be set two different ways.

# Way 1:
@optimizations {
    @identical_expressions: false;
};

# Way 2:
@optimizations.identical_expressions: false;

This time, we'll want to set the distance_literals flag to adjust. (solve is currently not supported), as the fix proposal in the compiler error message suggets:

@distance_literals: adjust;
let A, B, C = Point();

AB, BC, AC = 1, 2, 3;

Doing so will make Geo-AID create an adjustable scalar that will serve as the distance unit.

Dealing with complicated figures

Every now and then you will stumble on a figure that is quite challenging to draw, even for Geo-AID. In these cases, it's worth knowing a few tricks to guide Geo-AID through them.

When Geo-AID generates a figure, it does so with a certain amount of workers, over multiple cycles, until a certain condition (currently: average quality delta over the last x cycles goes below a certain value) is met. That's a lot of different generation parameters and all of them are modifiable.

  1. Worker count (-c option, 512 by default)

By modifying this parameter, you change how many different versions of a generation cycle are created. The higher the value, the more likely Geo-AID is to find the right spot for every point. It will, however, take more time and it might make certain flaws of Geo-AID's generation more visible.

  1. Generation break average delta treshold (-d option, 0.0001 by default)

Lowering this makes Geo-AID go on with generation for a little longer, essentially postponing the moment it decides it won't really get much better.

  1. Count of last records used in calculating the average delta (-m option, 128 by default)

Increasing this makes Geo-AID take more of the last cycles into consideration when deciding whether to stop.

  1. Maximum adjustment per generation cycle (-a option, 0.5 by default)

This modifies how much can a single point/scalar be changed when adjusting for another cycle. Keep in mind that this is only a base for calculations. In reality, the amount of adjustment allowed depends on the given point's quality and is different between different workers to allow both big and small changes in the same generation cycle.


Usually, the most visible effect comes from increasing the worker count. There is also a way to modify Geo-AID's behavior outside of its parameters. You can do so by modifying the point_bounds flag. Enabling them adds rules for points to be contained within (0,0) -> (1,1) range. This will heavily afftect the generation process and severely increase the time it will tak to complete. The result might not be the desired one, so don't expect too much.

Ultimately the best way of increasing odds for Geo-AID is to write the script as best as you can, relying strongly on defining points with expressions. The golden rule is: the less rules, the better.

Command-Line Interface of Geo-AID

Command Overview:

Geo-AID

Usage: Geo-AID [OPTIONS] <INPUT> <OUTPUT>

Arguments:
  • <INPUT> — The input script file
  • <OUTPUT> — The output target
Options:
  • -d, --delta-max-mean <DELTA_MAX_MEAN> — The maximum mean quality delta. Geo-AID will keep doing generation cycles until the average quality delta over the last m cycles gets below d.

    Default value: 0.0001

  • -c, --count-of-workers <COUNT_OF_WORKERS> — The count of threads to use for generation

    Default value: 512

  • -m, --mean-count <MEAN_COUNT> — The count of last deltas to include in mean calculation. Geo-AID will keep doing generation cycles until the average quality delta over the last m cycles gets below d.

    Default value: 128

  • -a, --adjustment-max <ADJUSTMENT_MAX> — Maximal adjustment of an adjustable during generation. Treated differently for different adjustables.

    Default value: 0.5

  • -r, --renderer <RENDERER> — What renderer to use.

    Default value: latex

    Possible values:

    • latex: The LaTeX + tikz renderer
    • svg: The SVG format renderer
    • json: The JSON (machine-readable) format renderer
    • raw: The raw (human-readable) format renderer
  • --width <WIDTH> — Canvas width (treated very differently for LaTeX)

    Default value: 500

  • --height <HEIGHT> — Canvas height (treated very differently for LaTeX)

    Default value: 500

  • -l, --log <LOG> — Where to put the log output. Geo-AID has a logging feature for concise information about the rendering process (quality and time).


This document was generated with the help of clap-markdown.

Renderers

Geo-AID supports four different renderers, also called drawers. One more is planned.

JSON

The popularized JSON format. Currently very not standardized, mostly useless - enforcing a better standard is work in progress.

Raw

A human-readable format, pure text. Contains descriptions of the positions of each object in the figure.

LaTeX

Using LaTeX, tikz and tikz-euclide, one of the two recommended ways of drawing the figure.

SVG

Outputs the figure in the svg format. One of the two - and the most tested - way of drawing the figure.

GeoGebra

Work in progress, Geo-AID will support outputting in the GeoGebra format importable in the very tool.

GeoScript reference

Syntax

This chapter describes the syntax of GeoScript. The notation used is the same as deifned in The Rust Reference. Geo-AID expects utf8 encoded files. All whitespaces are ignored beyond distinguishing separate tokens

Display Options

Syntax
Display Properties :
   [ Property (; Property)* ]

Property :
   NAMED_IDENT = PropertyValue

PropertyValue :
      NUMBER
   | IDENT

Display options are a simple sequence of key-value pairs used to represent certain options regarding how the figure should be displayed. They're accepted in expressions and variable definitions. Display options with invalid values will cause an error and the ones with invalid names will be ignored (likely to change in the coming versions).

Expressions

Syntax
Expressions<iter> :
      ImplicitIteratoronly if iter = true
   | SimpleExpression
   | Expression<iter> BinOp Expression<iter>;

BinOp :
   + | - | * | /

SimpleExpression :
   SimpleExpressionKind DisplayOptions?

SimpleExpressionKind :
      IDENT
   | NUMBER
   | ExprCall
   | UnOp SimpleExpression
   | ( Expression<true> )
   | ExplicitIterator
   | PointCollectionConstructor

ExprCall :
   NAMED_IDENT ( (Expression<false> (, Expression<false>)*)? )

UnOp :
   -

PointCollectionConstructor :
   & ( Expression<false> (, Expression<false>)* )

Expressions represent all values in GeoScript. A simple example of an expression is a variable reference with the variable's value or a number literal. After most expressions display options can be given, modifying how the expression affects the final figure visually.

Functions

Using a typical call syntax (funcname(arg1, arg2, ...)) one can also call functions with specified parameters. Functions can modify the visual output of the figure, e. g. add a line/ray. This behavior can be usually modified using display options. Some functions accept parameter groups, allowing infinite number of parameters. All functions return a single value. Implicit iterators cannot be used in function parameters, unless surrounded by parenthesis.

Operators

Binary operators all have the standard mathematical operation order. Unary operators always precede binary operators and implicit iterators always precede all operators. You can define your own order with parenthesis.

Currently, Geo-AID supports only addition, subtraction, multiplication and division as binary operators and negation as unary.

Point Collections

Expressions can also be used to construct point collections out of other expressions with &(A, B, ...) syntax. All expressions inside must be convertible to points.

Figure

Syntax
Figure :
   Statement*

Statement :
      FlagStatement
   | LetStatement
   | RuleStatement    | ;

A Figure describes how a figure should be generated in terms of generator flags, variable definitions and rules.

Flags

Syntax
FlagStatement :
   FlagName FlagValue

FlagName :
   @ NAMED_IDENT (. NAMED_IDENT)* :

FlagValue :
      NAMED_IDENT
   | FlagSet
   | NUMBER

FlagSet :
   { FlagStatement* }

Flags modify the behavior of Geo-AID's generator. They have default values, though some of them need to be explicitly specified to enable certain features (e. g. distance_literals).

A flag statement composes of the flag's name and its value. Each flag has a predefined type and will only accept values of that type. Identifier flags accept identifiers in general, though usually only a subset of identifiers is valid, representing certain behavior options. Boolean flags are used to enable or disable certain features/modifications to the standard behavior. They accept 1, true, enabled and yes as a true value and 0, false, disabled and no as a false value. Number flags may accept floats or integers, depending on the flag. Flag sets are special flags that categorize other flags. If you want to modify multiple flags of the same category, simply set the value of the parent set flag to a flag set with the respective statements.

Flag statements also accept a syntatic sugar for flag indexing. Instead of writing

@optimizations {
    @identical_expressions: false
}

You can simply write

@optimizations.identical_expressions: false

Identifiers

Lexer
IDENT :
      NAMED_IDENT
   | POINT_COLLECTION

NAMED_IDENT :
   Start Continue*

POINT_COLLECTION :
   (Point '*)+

Where Start is any unicode character with the Alphabetic property or an underscore (_) character, Continue is Start or a tick (') character and Point is any unicode character with the Uppercase property.

Identifiers mostly represent variables, though they may also serve as a rule operator, a function, a value for a display property or a flag value.

Point collections are a special kind of identifiers. They essentially represent a sequence of variables, each being a point.

Iterators

Syntax
ImplicitIterator :
   Expression<false> (, Expression<false>)+

ExplicitIterator :
   $ ( Expression<false> (, Expression<false>)* )

Iterators can be used in let statements and rules on both sides. A sequence of expressions separated by a comma is called an implicit iterator. Using these, multiple lines of a script can be collapsed into a single one. For example:

let A, B, C = Point();

AB = AC, BC;

Iterators are expanded into multiple rules/statement by simply iterating over the given sequence. Implicit iterators take precedence over any arithmetic operators. Here's a few examples:

AB, BC = CD, EF;

# Becomes
AB = CD;
BC = EF;
AB < XY + YZ, OI;

# Becomes.
AB < XY + YZ;
AB < XY + OI;

whereas

AB < (XY + YZ), OI;

# Becomes

AB < XY + YZ;
AB < OI;

To use implicit iterators inside a function call, simply put parentheses around them: intersection(AB, (KL, XY))

Another type of an iterator is an explicit iterator. These are written in the following way:

AB = $1(AC, BC);

The above example is equivalent to just writing

AB = AC, BC;

The number after the dollar sign is the id of the iterator. If only a single id is used, they function just like implicit iterators. However, when using multiple different ids, more complicated results can be achieved:

$1(AB, CD) < $2(XY, YZ);

# Becomes
AB < XY;
CD < XY;
AB < YZ;
CD < YZ;

Explicit iterators can also be nested, allowing for even more complicated rules. For example:

$1(AB, BC) > $1(x, $2(a, b)), $3(9, 4, 3);

# Becomes
AB > x;
BC > a;
BC > b;
AB > 9;
AB > 4;
AB > 3;
BC > 9;
BC > 4;
BC > 3;

Iterators have a few rules. Not obeying them causes compilation errors.

  • All implicit iterators have an id of 0;
  • All iterators of the same id must have the same length;
  • The left hand side of let statements only accept implicit iterators;
  • The right hand side of let statements accepts at most one level of iteration;
  • The right hand side of a let statement may only contain iterators, if so does the left side;
  • All iterators must have at least two variants;
  • An iterator with id x must not contain another iterator with id x;
  • Iterator length must not exceed 255;
  • Iterator id must be an integer;

Numbers

Lexer
NUMBER :
   Digit+ (. Digit+)?

Where Digit is an ASCII digit (0-9). Either integers or decimals.

Rules

Syntax
RuleStatement :
   Expression<true> RuleOp Expression<true>* ;

RuleOp :
      < | <= | = | >= | >
   | IDENT
   | ! RuleOp

Rules are the basic building blocks of a figure. They define relationships between figure objects. Geo-AID attempts to generate a figure that obeys them as best as it can. Rules tie two expressions (left and right hand side) with a relationship, otherwise known as the rule operator. Currently supported rule operators are all comparison operators. When given an identifier, a proper defined rule operator is looked up and compiled accordingly (currently none supported). Rules can also be inverted with an exclamation mark in front of the operator.

Variables

Syntax
LetStatement :
   let VariableDefinition (, VariableDefinition)* = Expression<true> (RuleOp Expression<true>)* ;

VariableDefinition :
   @ IDENT DisplayOptions?

A let statement creates variables given on the left hand side. The lhs of the statement can contain multiple variables. In that, case if the rhs has no iteration, all variables will be set to the given definition (no the same value, though). If there is one level of iteration, all variables will get their respective definition. More levels of iteration are not allowed.

The rhs expression of the statement can either become the variable's definition or it can be unpacked onto a point collection.

After each variable name there can be display options given, modifying how the construct is displayed.

The let statement accepts rules after its right hand side. They behave as if the lhs was a sequence of variable accesses in a 0-id iterator.

Types

GeoScript has two kinds of types: primitives and bundles.

Primitives - the points, lines, scalars and circles, are the building blocks of every value in GeoScript. Bundles, on the other hand, consist of multiple primitives.

Primitives

Scalar

A scalar is a simple real value with a unit - a unit is a product of integer powers of simple units. The simple units are:

  • Distance
  • Angle

Any scalar, whose unit cannot be determined, is assumed to be unitless. Scalars in this reference are denoted as Scalar(<unit>).

Note: A literal will never be coerced to an angle, since that would introduce uncertainty whether it should be treated as given in radians or degrees. Instead, look for their respective functions.

Point

A point is defined as a point on a euclidean plane. Denoted as Point.

Circle

A circle is given a center and a radius. It is a set of points with the distance to its center equal to its radius. Denoted as Circle.

Line

A line is a line in euclidean sense. Denoted as Line.

Bundle types

Bundle types are zero-cost abstractions over primitives. There are two types of bundles: point collections and named bundles.

Point collections

Point collections are simply ordered collections of points. It is never a seperate entity, only an abstraction over a set of points. Denoted as <length>-P. If <length> is given as 0, it means a collection of any length. Most functions that accept points as arguments, also accept point collections.

Named Bundles

Named bundles are similar to structs in C. They have names and named fields of any type (not yet accessible). Denoted with their unique names different from the names of any other type.

Segment

Segment {
    A: [Point](primitives.md#point),
    B: [Point](primitives.md#point)
}

Segments have two fields denoting their ends.

Operators

Standard arithmetic operations - addition (+), subtraction (-), multiplication (*) and division (/) are only allowed between scalars. Addition and subtraction must only be performed between scalars of the same unit, whereas multiplication and division can be done with any two scalars. The resulting unit will simply be a product of the operation. Beyond that, negation with the - operator can be performed on any scalar.

Functions

angle

  • angle(ABC: [3-P](./types/bundle-types.md#point-collections))
  • angle(A: [Point](./types/primitives.md#point), B: [Point](./types/primitives.md#point), C: [Point](./types/primitives.md#point))

Return type: Scalar (angle)

Returns: measurement of the angle ABC

  • angle(k: [Line](./types/primitives.md#point), l: [Line](./types/primitives.md#line))

Return type: Scalar (angle)

Returns: measurement of the angle between k and l. Which angle, depends on the order of the lines. For predictable outcome, the point versions are strongly recommended.

bisector

  • bisector(AB: [2-P](./types/bundle-types.md#point-collections))
  • bisector(A: [Point](./types/primitives.md#point), B: [Point](./types/primitives.md#point))

Return type: Line

Returns: a bisector of the segment AB - a perpendicular line passing through its center.

  • bisector(ABC: [3-P](./types/bundle-types.md#point-collections))
  • bisector(A: [Point](./types/primitives.md#point), B: [Point](./types/primitives.md#point), C: [Point](./types/primitives.md#point))

Return type: Line

Returns: a bisector of the angle ABC - a line between lines AB and BC, where each point is in the same distance from both of these lines.

Circle

  • Circle(center: [Point](./types/primitives.md#point), radius: [Scalar (distance)](./types/primitives.md#point))
  • circle(radius: [Scalar (distance)](./types/primitives.md#point), center: [Point](./types/primitives.md#point))

Return type: Circle

Returns: a circle with the given center and radius.

  • Circle()

Return type: Circle

Returns: a circle with an adjusted (free point) center and an adjusted (free scalar) radius.

degrees

  • degrees(value: [Scalar (no unit)])

Return type: Scalar (angle)

Returns: an angle with the given measurement in degreees. Related: radians

dst

  • dst(AB: [2-P](./types/bundle-types.md#point-collections))
  • dst(A: [Point](./types/primitives.md#point), B: [Point](./types/primitives.md#point))

Return type: Scalar (distance)

Returns: the distance between points A and B.

  • dst(P: [Point](./types/primitives.md#point), k: [Line](./types/primitives.md#line))
  • dst(k: [Line](./types/primitives.md#line), P: [Point](./types/primitives.md#point))

Return type: Scalar (distance)

Returns: the distance between point P and line k.

  • dst(value: [Scalar (no unit / distance)])

Return type: Scalar (angle)

Returns: the value with a distance unit.

intersection

  • intersection(k: [Line](./types/primitives.md#point), l: [Line](./types/primitives.md#line))

Return type: Point

Returns: intersection of lines k and l.

mid

Note: The following functions allow any positive numbers of arguments.

  • mid(v_1: [Scalar (any unit u)](./types/primitives.md#Scalar), v_2 [Scalar (the same unit u)](./types/primitives.md#Scalar), ..., v_n: [Scalar (the same unit u)](./types/primitives.md#Scalar))

Return type: Scalar (the same unit u)

Returns: The average value of v_1, v_2, ... v_n.

  • mid(P_1: [Point](./types/primitives.md#Point), P_2 [Point](./types/primitives.md#Point), ..., P_n: [Point](./types/primitives.md#Point))

Return type: Point

Returns: The middle point of P_1, P_2, ... P_n. Special cases: when n=2, the middle of a segment; When n=3, the centroid of a triangle.

parallel_through

  • parallel_through(P: [Point](./types/primitives.md#point), k: [Line](./types/primitives.md#Line))
  • parallel_through(k: [Line](./types/primitives.md#line), P: [Point](./types/primitives.md#Point))

Return type: Line

Returns: a line parallel to k, passing through P.

perpendicular_through

  • perpendicular_through(P: [Point](./types/primitives.md#point), k: [Line](./types/primitives.md#Line))
  • perpendicular_through(k: [Line](./types/primitives.md#line), P: [Point](./types/primitives.md#Point))

Return type: Line

Returns: a line perpendicular to k, passing through P.

Point

  • Point()

Return type: Point

Returns: an adjusted (free) point.

radians

  • radians(value: [Scalar (no unit)])

Return type: Scalar (angle)

Returns: an angle with the given measurement in radians. Related: degrees

Segment

  • Segment(AB: [2-P](./types/bundle-types.md#point-collections))
  • Segment(A: [Point](./types/primitives.md#point), B: [Point](./types/primitives.md#point))

Return type: Segment

Returns: the semgent AB.

Rule operators

Comparison

The operators <, <=, >, >= are only allowed between Scalars of the same unit. They are simple comparison operators with their rules evaluated based on the relative difference between the two values.

The operator = (and its negation, !=) is allowed between Scalars of the same unit and Points. Its rule is evaluated based on the absolute distance between the two values.

lies_on

  • P: [Point](./types/primitives.md#point) lies_on k: [Line](./types/primitives.md#Line)

Tells Geo-AID that point P lies on (has zero distance) from line k. Note: zero distance rules do not have any impact on the distance variable and decrease figure stability much less than other distance rules.

  • P: [Point](./types/primitives.md#point) lies_on k: [Segment](./types/bundle-types.md#Segment)

Tells Geo-AID that point P lies on (has zero distance) from the line of segment k and between its ends. Note: zero distance rules do not have any impact on the distance variable and decrease figure stability much less than other distance rules.

  • P: [Point](./types/primitives.md#point) lies_on omega: [Circle](./types/primitives.md#Circle)

Tells Geo-AID that point P lies on (has zero distance) from circle omega. Note: zero distance rules do not have any impact on the distance variable and decrease figure stability much less than other distance rules.

  • col: [0-P](./types/bundle-types.md#) lies_on omega: [Circle](./types/primitives.md#Circle)

Tells Geo-AID that points in the collection col lie on (have zero distance) from circle omega in exactly the given order. Note: zero distance rules do not have any impact on the distance variable and decrease figure stability much less than other distance rules.