Home • Gallery • Tutorials • Download • Purchase • Site Map

Program Variables

Fractal Science Kit program variables are identifiers used to hold data.

A variable's type determines the kind of data that can be stored in the variable. Most variables represent complex numbers and their type is Complex. If you do not declare a variable, it is assumed to be Complex. Other built-in types include Color, Circle, Vector, Triangle, Affine, Mobius, TrappedPointInfo, AlternatePointInfo, SymmetryTransformationInfo, and PerlinNoise. These types, define specialized objects used to group several related fields together, and can be found in the built-in macros. You can define your own types by placing Object statements in My Macros.

To declare a variable you use the variable declaration statement:

[const] <Type> <VariableName> [ = <Expression> ]

The variable name must be a valid identifier. The type must be Complex or an existing Object name and is required. The optional const keyword is used to declare a constant and may appear only in the global section. An expression can be used to initialize the variable. If the expression is given, its type must match that declared for the variable.


const Complex radius = 1
Complex p = Cis(Math.PI/4)
Mobius identity = Mobius(1, 0, 0, 1)
Circle cir

This example declares 4 variables named radius, p, identity, and cir. The first 2 hold complex numbers and the last 2 hold a Mobius transformation and a circle, respectively. The first 3 statements initialize the variable as well. Finally, the first statement declares radius as a constant using the optional keyword const. Declaring a variable as const can be done only in the global section and states that the variable will not be changed outside the global section. This allows the compiler to optimize statements that reference the variable in other sections.

In most cases, you will want to initialize a variable before you use it, but this is not required. Complex variables are set to 0 during compilation. All the fields within each declared object are set to 0 during compilation, as well. Object variables must be declared (but not necessarily initialized) before they are used.

Special types such as Integer, Float, Boolean, are not supported and you should use Complex variables for those data types. While this is arguably less efficient, it results in a simpler language definition.

Clearly, many functions and some of the operators take Integer, Float, or Boolean operands/arguments, and return Integer, Float, or Boolean results. When an Integer, Float, or Boolean argument is required, the function or operator simply uses the real component of the complex value coerced into the appropriate type. Where a Boolean is required, we interpret 0 as false and non-0 as true. Built-in constants True and False are provided to aid in program clarity. Return values are handled in much the same way; i.e., the coerced value is stored in the real component, and the imaginary component is set to 0.

All Complex variables have a real component and an imaginary component. These are referenced by using the .r and .i qualifiers, respectively.


point.r = 0
point.i = 1

Here, point.r is the real component of the complex value and point.i is the imaginary component of the complex value. The above example and each of the following statements are equivalent:

point = 0+1i
point = 1i
point = Complex(0, 1)

Complex values are frequently given in polar form by specifying a radial distance or magnitude and an angle measured counterclockwise from the real axis. When a Complex variable holds a polar representation, the .a qualifier can be used in place of .i qualifier, for clarity.


point.r = 1
point.a = Math.PI/2

Here, point.r is a radial distance and point.a is an angle expressed in radians.

Finally, when a complex value is used to represent a point on the complex plane for the purpose of displaying graphics, it is sometimes convenient to use the .x and .y qualifiers in place of the .r and .i qualifiers.


point.x = 1
point.y = 2

Here, point.x and point.y represent the x and y coordinates associated with the complex value 1+2i.

These qualifiers are simply a notational convenience that can be used to clarify your code and that any processing related to the complex value is not affected. That is, each complex value has 2 components. The first component is accessed using the .r or .x qualifiers. The second component is accessed using the .i, .a, or .y qualifiers. The actual representation of the complex value is the responsibility of the developer.

Two functions are available to create a complex value from 2 floats:

z = Complex(real, imag)
z = Polar(radius, angle)

Both these functions, in fact, are equivalent since they both simply return a complex value based on the given arguments. The sole reason for providing both is to increase the readability of your code. Functions are also provided to convert between complex and polar representations.


z = Complex(0, 1)
p = ComplexToPolar(z)
p = Polar(1, Math.PI/2)
z = PolarToComplex(p)

In this example, z and p represent the complex value 0+1i. In the 1st case we set z directly and convert z to polar form (p) using the ComplexToPolar function. In the 2nd case, we set p directly and convert p to complex form (z) using the PolarToComplex function.

All operators and built-in functions (with the exception of the function PolarToComplex) expect their operands to be given in the complex (not polar) representation.


Copyright 2004-2019 Ross Hilbert
All rights reserved