Skip to content

Spatial

This is perhaps the most important entry in this section. It deals with glyphs dealing in vector, block position, quaternion, frame and plane species. These species help practitioners define points in space, shaping their spell effects into the desired form.

Vectors are the key species to represent space, movement and direction. They can directly represent a minecraft coordinate position in the form (x, y, z), and they can also capture direction (eg, vector (0, 1, 0) represents going 1 block up the y-axis).

num, num, num$() → vec$() Pops three numbers and uses those to compose a vector, which is pushed onto the capsum. eg. 1, 2, 3 → (1, 2, 3), where 3 was at the head initially.

number$() → vector$() Pops a number and composes a vector where all the coefficients are equal to that number. eg. 2 → (2, 2, 2)

vec$() → num, num, num$() Pops a vector and returns its coefficients as individual number species on the capsum. eg. (x, y, z) → x, y, z, where the coefficient z ends up at the head.

vec$() → vec$() Scales a given vector to make it into a unit vector. Essentially scales the vector to have a length of 1 while preserving direction.

vec, vec$() → vec$() Projects the vector on the head onto the vector below. Essentially returns the image of the vector at the head on the vector below the head.

vector$() → number$() Pops a vector and returns the number corresponding to its length.

vec, vec$() → num$() Pops two vectors off the capsum and returns the number corresponding to the angle between the two vectors in degrees.

number$() → vector$() Pops a number and returns a random vector with length equal or less than the popped number. Represents a random vector stretching from the origin to a random point within the radius given by the popped number.

Block positions are similar to vector species in that they represent space. However, block positions are directly linked to each block in the world. They allow practitioners to interact with block themselves. Likewise, face species represent the faces of blocks (up, down, north, south, east and west).

vector$() → position$() Pops a vector and returns the block position containing the vector. Not reliable to process vectors from results, as these are often on the border between two blocks.

vector$() → position$() Pops a vector and returns a block position corresponding to the block the vector is in. Useful for processing vectors from results, as it can reliably return the block position corresponding to the impacted block.

vector$() → position$() Pops a vector and returns a block position corresponding to the block on the face the vector hit. Useful for processing vectors from results, as it can reliably return the block position of the block on the face of the impacted block that was hit by the projectile.

position$() → vector$() Takes a block position and returns the vector corresponding to the centre of the position.

vec, pos$() → face$() Takes a vector and a position and returns the face on the block the vector is nearest to. Useful for computing the face impacted by a projectile. It is important to remember faces only encode direction, not position in space.

vec, face$() → vec$() Pops a face and a vector off the capsum, and reflects the vector along the given face.

Quaternions are a species that can be used to represent rotations, convenient due to their relative simplicity. They are composed of 4 numbers, one to represent the angle of rotation, and the other three represent the axis of rotation. A quaternion representing a rotation by A about the axis determined by vector V can be represented as follows: [cos (A/2), V x sin (A/2)] which is equivalent to...

[cos A/2, V1 x sin(A/2), V2 x sin(A/2), V3 x sin(A/2)].

To determine the direction of the rotation, use the quaternion right hand rule, which readers are recommended to study.

num, num, num, num$() → quat$() Builds a quaternion from the 4 numbers at the top of the stack. eg. 2, 3, 4, 5 → (2, 3, 4, 5)

vec, num$() → quat$() Builds a quaternion from a given angle (in degrees) and axis. eg. (0, 1, 0), 180 → (cos 90, 0, sin 90, 0) = (0, 0, 1, 0)

num, num, num$() → quat$() Pops 3 number representing yaw, pitch and roll angles in degrees and creates a quaternion by applying yaw, pitch and roll in that order. The input expects roll at the top, followed by yaw, which is followed by pitch.

quat, quat$() → quat$() Takes two quaternions, and composes them. Composition essentially multiplies quaternions to create a single quaternion that combines both of the rotations represented by its factors. This operation is not commutative.

quat$() → quat$() Takes a quaternion and returns its conjugate. Essentially changes the sign of each of a quaternion’s vector components, resulting in a quaternion that represents the opposite rotation to the original.

quat$() → quat$() Scales a quaternion such that its norm equals 1. This is necessary to ensure a rotation is valid in 3D space.

quat$() → num$() Returns the norm of a given quaternion. The norm of a quaternion can be understood to be its ‘magnitude’, the square root of each of its components squared. eg. (a, b, c, d) → sqrt(a^2 + b^2 + c^2 + d^2)

vec, quat$() → vec$() Applies the rotation embedded by a quaternion to a vector, returning the resulting vector.

quat, quat, num$() → quat$() Takes two rotations, calculates the shortest possible arc between them, and returns a quaternion a portion of the way between them, determined by the number at the head. eg. q0, q1, t → quat that is t percent of the way between q0 and q1

Frames are structures that represent a set of points relative to each other. The important feature of frames is that the relative positions of the points do not change as the frame moves around, allowing practitioners to define structures that remain coherent as they are translated and rotated.

vec, vec, vec, vec$() → frame$() Creates a frame by taking the 4th vector as the origin and the three vectors above it as the axes that form the basis of the frame.

vec, vec, vec$() → frame$() Create a frame by taking the 3rd vector from the head as the origin, and the top 2 as a pair of axes from which the 3rd axis needed to span 3D space is constructed. The third axis is simply the vector orthogonal to the top 2 vectors in the capsum.

frame, vec$() → vec$() Takes a vector representing a coordinate in the world and returns the vector corresponding to the coordinate within the frame.

frame, vec$() → vec$() Takes a vector representing a coordinate in the frame and returns a vector corresponding to the coordinate in the world.

frame, quat$() → frame$() Rotates a frame’s orientation by an axis in the world.

frame, quat$() → frame$() Rotates a frame’s orientation by an axis expressed in terms of the frame’s basis.

frame, vec$() → frame$() Translates the frame’s origin by a vector in terms of the world.

frame, vec$() → frame$() Translates the frame’s origin by a vector in terms of the frame.

Planes are a species that can represent a set of points that when combined, forms a plane. They are useful in order to construct sets of points in space that are aligned with each other along some axis. They have an origin point and a normal, representing a line perpendicular to the plane.

vec, vec$() → plane$() Creates a plane by reading a normal vector on the head and a vector for its origin point, just below the head. eg. origin, normal → plane on the origin with the specified normal

plane, vec$() → vec$() Takes a point and projects it onto the given plane.

plane, vec$() → vec$() Takes a point and returns a vector corresponding to the reflection of the point by the plane.

plane, vec$() → num$() Takes a point and returns the shortest distance between the point and the plane’s surface.

plane$() → vec, vec$() Takes a plane and returns a pair of vectors which span it (vectors which can be used to construct any other vector on the plane).

plane$() → vec$() Takes a plane and returns its normal vector.

These glyphs rely on places to arrange points in a specific configuration. Using these glyphs, practitioners can create different shapes on a given plane, allowing them to structure and shape their spell effects more precisely.

plane, vec, num, num$() → list$() Takes a plane, a centre point, and 2 numbers describing radius and number of points, with the latter on the head, and returns a list of vectors representing equally-distributed points on the circle. eg. plane, origin, radius, samples → list of points

plane, vec, num$() → vec$() Takes a plane, a centre point and a radius, and returns a random vector on the plane within the radius centred around the origin point.

plane, vec, num, num, num$() → list$() Takes a plane, a centre point and 3 numbers describing radius, sides and rotation (in degrees), and returns a list of vectors corresponding to the vertices of a regular polygon of the specified number of sides. eg. plane, origin, radius, sides, angle → list of points

plane, vec, num, num, num, num$() → list$() Takes a plane, a centre point, and 4 numbers describing radius, starting and ending angles and number of points. Returns a list of points on the arc on the plane, of the specified radius, stretching between the starting and ending angles.

eg. plane, origin, radius, angle 1, angle 2, samples → list of points

plane, vec, num, num, num, num$() → list$() Takes a plane, a centre point and 4 numbers describing number of rows, columns, separation between rows and between columns. Returns the set of points at the vertices of the specified grid on the plane (where the rows intersect the columns).

eg. plane, origin, column num, row num, distance col., distance row → list of points

plane, vec, num, num, num, num, num$() → list$() Samples points on an Archimedean spiral. Takes a plane, a centre point and 5 numbers describing the position of each arm (a + b x θ) and the number of points. Returns a set of points on the described spiral.

eg. plane, origin, a, b, θ1, θ2 → list of points