Magician is in extremely early stages and is a general-purpose mathematical engine for generating and visualizing data, built with a simple API in mind.
Magician is built around two core abstractions, Multis and IMaps.
A Multi is recursively-defined geometry. Anything drawn to the screen is a Multi, or a Texture, which is always a member of a Multi
Each Multi stores its position relative to its parent, but not its absolute position. A Multi contains flags that determine how it is drawn, either as a plot, or a filled/outlined geometrical shape.
An IMap represents a one-dimensional mathematical function f(x). They can be defined in multiple ways, such as with a lambda, or with built-in features like a sequence of polynomial terms. IMaps cam be used to define dynamic behaviour or to render plots in the form of a Multi.
A Multimap is an IMap with an arbitrary number of inputs and outputs. This is useful for defining parametric movement/plots.
Magician currently offers limited user interactivity, defineable through IMaps.
Currently, Magician has basic functionality, but is not ready for general use. It is best used by writing a class that inherits Spell, adding that Spell to a Spellcaster, and calling the Spell methods from the SDL loop. A spell consists of the Preloop, which runs once and the Loop, which runs every frame. The following examples are written in the Preloop.
// Create an equilateral triangle with radius 60 in the upper-right quadrant
Origin["myTriangle"] = RegularPolygon(100, 100, 3, 60);// Create a pentagon with radius 100, with a random easy-to-see colour
Origin["myPentagon"] = RegularPolygon(5, 100).Colored(
HSLA.Random(saturation: 1, lightness: 1, alpha: 120)
);...
// Let that pentagon track the mouse cursor
Origin["myPentagon"].DrivenXY(
x => Events.MouseX,
y => Events.MouseY
);...
// Now let that pentagon revolve about the origin, while still tracking the mouse
Origin["myPentagon"].DrivenPM(
p => Data.Env.Time,
m => m
);...
// Let that pentagon rotate about its axis
Origin["myPentagon"].Sub(m => m
.DrivenPM(
p => p + 0.1,
m => m
)
);Origin["parametric"] = new Multimap(1,
x => 180 * Math.Cos(x / 3),
y => 180 * Math.Sin(y / 7)
).TextAlong(-49, 49, 0.3, "Here's an example of a Multimap with 1 input and two outputs being used to draw text parametrically",
new RGBA(0x00ff9080));Thanks to these people for sharing their knowledge.