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 Maps.
A Multi is a tree of 3-vectors that defines geometrical objects
Each Multi stores its position relative to its parent in the tree. A Multi contains flags that determine how it is drawn, either as a plot, or a 2D/3D geometrical shape.
Maps represent mathematical functions from some number of inputs to some number of outputs
The most general case, a relational map allows for any number of ins to any number of outs
An IPM allows for any number of ins, but only one out. This is a solved equation, a function t = f(x,y,z,...)
A ParamMap allows for any number of outs, but only one in. This is a parametric equation f(t) = (x,y,z,...)
A DirectMap allowed for zero or one ins, and exactly one out. This is a function of a single variable y = f(x)
Magician currently offers limited user interactivity. Controls and Sensors defineable through Maps
Currently, Magician has basic functionality, but is not ready for general use. It is best used by writing a class that inherits Spell, loading it with the 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.