Baroque Ghosts
Originally posted February 14, 2005. See above for further entries.
Note: This was originally posted with images which were subsequently lost. They will eventually be re-instated.
I've always found programming satisfying because it's essentially a problem solving activity. Flash is one thing, but coding in a 3D program is much more exciting. Most contemporary 3D software packages have some kind of scripting language built in and I've been using C4D's COFFEE language to write some very basic scripts that generate graphics in three dimensions.

As far as programming goes, the script used to make these entities is so basic it's almost embarrassing that I'm discussing it. Starting at 0 the script picks a random point in space within a 200 unit radius and draws a spline to it. Then it does this same action again and again until you tell it to stop. This results in a meandering line (b-spline, if you're interested) that curves in all three dimensions. I've run the script twice and made two of these spline jumbles. In the images below one is seen in red and the other in black.

Beyond the simple task of 'designing' the code, the primary task with a project like this is to edit the results into something aesthetically interesting, which essentially means picking revealing viewing angles.

These two jumbles which are occupying different positions in space are then connected with a loft. Essentially this means connecting point 1 on the first jumble to point 1 on the second jumble, point 2 to point 2, and so on until all the points are connected across and you have a surface that spans from the first jumble to the second. Below you will see the key lines of the lofted surface drawn as dashed lines.

Finally, after we've found an angle that's good and set up the lofted surface it's time to render. If you're interested I've included the COFFEE code used to generate these graphics below, otherwise enjoy some more ghosts:


And now some COFFEE:
// creates an object called "Spline"
// if one does not exist and starts adding randomly placed points
// which are positioned relative to the axis.
// updates on refresh, so hit play and watch the curve draw
// then hit stop when you've had enough
// portions poached from: http://www.nthd.org/nthd/
main(doc,op)
{
//get document info
var doc = GetActiveDocument();
var obj, pointCount, points, backupTags, variableChanged;
if (!doc->FindObject("Spline")) {
println("making a new spline");
//create new spline
obj = new(SplineObject);
pointCount = 2;
//fill create null points
points = new(array,pointCount);
obj->SetPoints(points);
// try to set the spline type....
var container = obj->GetContainer();
container->SetData(SPLINEOBJECT_TYPE,3);
obj->SetContainer(container);
// now that we've modified the spline we need to tell the mothership
// and before doing that we'll set up a rig to deal with low
// memory conditons
//create messageing object to tell spline points were added
variableChanged = new(VariableChanged);
// create the backup
backupTags = new(BackupTags);
backupTags->Init(obj);
// set change
variableChanged->Init(0, pointCount);
//if the update failed, restore to saved data
if (!obj->Message(MSG_POINTS_CHANGED, variableChanged)){
backupTags->Restore();
return FALSE;
}
// actually position the points
obj->SetPoint(0,vector(0,0,0));
obj->SetPoint(1,vector(100,100,100));
//Insert the object into scene
obj->Message(MSG_UPDATE);
doc->InsertObject(obj,NULL,NULL);
} else {
println("already got one");
obj = doc->FindObject("Spline");
//println("It's ",obj->GetPointCount()," long.");
pointCount = obj->GetPointCount()+1;
var currentPoints = obj->GetPoints();
currentPoints[pointCount-2] = nil;
// now that we've modified the spline we need to tell the mothership
// and before doing that we'll set up a rig to deal with low
// memory conditons
//create messageing object to tell spline points were added
variableChanged = new(VariableChanged);
// create the backup
backupTags = new(BackupTags);
backupTags->Init(obj);
// set change
variableChanged->Init(0, pointCount);
//if the update failed, restore to saved data
if (!obj->Message(MSG_POINTS_CHANGED, variableChanged)){
backupTags->Restore();
return FALSE;
}
var r = new(Noise);
var rx = r->SNoise(time(),time(),time());
var ry = r->SNoise(time()+1,time()+1,time()+1);
var rz = r->SNoise(time()+2,time()+2,time()+2);
var mod = 1000;
println("placing point at ",rx,", ",ry,", ",rz);
// get the previos point
var prev = obj->GetPoint(pointCount-2);
// position it
obj->SetPoint(pointCount-1,vector(prev.x+mod*rx,prev.y+mod*ry,prev.z+mod*rz));
// Finally, update object in display
obj->Message(MSG_UPDATE);
}
} // end script
And if you're still here: something else that's scripted.