The concept of the design revolves around the Cotard Delusion, which is a rare mental illness in which the affected person holds the delusional belief that they are already dead, do not exist, are putrefying, or have had part of their body distorted, destroyed or taken.
The idea is to take an existing surface ( represented by the height map of the owl model we used ) and convert it into an array of coordinate points, and create three additional points of disturbance, each interacts with the base geometry to destroy and rebuild a distorted vortex, and eventually turning into a brand new geometry.
The core to our design is disturbance and the reconfiguration of the identity of the geometry. Post-processing involved grasshopper / rhino manipulation and rendering. Surface Deformation and Discretization was a collaborative effort based on C#.
private void Runscript (
Surface srf, // original input geometry
int uCount, int vCount, // scaling _ density of points
double localxa, double localya, // first point of disturbance
double localxb, double localyb, // second point of disturbance
double localxc, double localyc, // third point of disturbance
double sizinga, double sizingb, double sizingc // size of disturbance
ref object A // output list of coordinates
)
// taken directly from lecture 12 - surfaces
double u0 = srf.Domain(0).Min;
double u1 = srf.Domain(0).Max;
double v0 = srf.Domain(1).Min;
double v1 = srf.Domain(1).Max;
double du = (u1 - u0) / (uCount - 1.0);
double dv = (v1 - v0) / (vCount - 1.0);
List<point3d> pt = new List<point3d>();</point3d></point3d>
// loop for reading point coordinates
for(int i = 0; i < uCount; ++i) {
for(int j = 0; j < vCount; ++j) {
double variaa = 1; // initialize values
double variab = 1;
double variac = 1;
// determining direction of distortion | left of point or right of point
if(localxa < i){ variaa = sizinga / (Math.Sqrt(Math.Pow(i - localxa, 2) + Math.Pow(j - localya, 2))); }
if(localxa > i){ variaa = -sizinga / (Math.Sqrt(Math.Pow(i - localxa, 2) + Math.Pow(j - localya, 2))); }
if(localxb < i){ variab = sizingb / (Math.Sqrt(Math.Pow(i - localxb, 2) + Math.Pow(j - localyb, 2))); }
if(localxb > i){ variab = -sizingb / (Math.Sqrt(Math.Pow(i - localxb, 2) + Math.Pow(j - localyb, 2))); }
if(localxc < i){ variac = sizingc / (Math.Sqrt(Math.Pow(i - localxc, 2) + Math.Pow(j - localyc, 2))); }
if(localxc > i){ variac = -sizingc / (Math.Sqrt(Math.Pow(i - localxc, 2) + Math.Pow(j - localyc, 2))); }
double u = u0 + i * du;
double v = v0 + j * dv;
Point3d p = srf.PointAt(u, v); // read original geometry coordinate value
// update point based on offset
double localoffset = variaa + variab + variac;
Point3d ad = new Point3d(localoffset, 0, 0);
Point3d f = p + ad;
// create bounding box and add point to list
double tolerancee = 10;
if(f.X < u1 + tolerancee && f.X > u0 - tolerancee && f.Y < v1 + tolerancee && f.Y > v0 - tolerancee){
pt.Add(f);
}
// disturbance point coordinate definition
double smallxa = localxa - (uCount * (sizinga) / 500) + i * (sizinga / 250);
double smallya = localya - (vCount * (sizinga) / 500) + j * (sizinga / 250);
double smallxb = localxb - (uCount * (sizingb) / 500) + i * (sizingb / 250);
double smallyb = localyb - (vCount * (sizingb) / 500) + j * (sizingb / 250);
double smallxc = localxc - (uCount * (sizingc) / 500) + i * (sizingc / 250);
double smallyc = localyc - (vCount * (sizingc) / 500) + j * (sizingc / 250);
double dista = Math.Sqrt(Math.Pow(smallxa - localxa, 2) + Math.Pow(smallya - localya, 2));
double distb = Math.Sqrt(Math.Pow(smallxb - localxb, 2) + Math.Pow(smallyb - localyb, 2));
double distc = Math.Sqrt(Math.Pow(smallxc - localxc, 2) + Math.Pow(smallyc - localyc, 2));
// defining circular boundary
// (13, 20 and 4.5 are arbitrary numbers in this case to scale for optimal visuals)
if(dista < sizinga / 13){
Point3d n = srf.PointAt(u, v);
Point3d q = new Point3d(smallxa + uCount / 4.5, smallya + vCount / 4.5, n.Z + 20);
pt.Add(q);
}
if(distb < sizingb / 13){
Point3d n = srf.PointAt(u, v);
Point3d q = new Point3d(smallxb + uCount / 4.5, smallyb + vCount / 4.5, n.Z + 20);
pt.Add(q);
}
if(distc < sizingc / 13 ){
Point3d n = srf.PointAt(u, v);
Point3d q = new Point3d(smallxc + uCount / 4.5, smallyc + vCount / 4.5, n.Z + 20);
pt.Add(q);
}
}
}
// output point
listA = pt;
Below(Fig 4) shows the result surface from the first part of the code. On the right is the direct result (with base trimmed) while on the left we have highlighted the original points and range of input variables.
Cylinders For the descretization section, we used cylinders as our constant. The below code allows the entire form to be rebuilt with multiple cylinders of the same radius. This constraint could be used for resurfacing / draping / structuring the physical prototyping. After creating this output, we re-evaluated our design and decided to leave it but used the Delauncy mesh for post-processing and rendering as our final deliverable.
private void RunScript (
List<point3d> pt, </point3d> // mesh vertices from rebuilt geometry
int size, // diameter of cylinders
ref object B // output
)
{
// establish new list using Rhino.Geometry.Extrusion namespace
List<extrusion> extrusions = new List<extrusion>();</extrusion></extrusion>
// loop for reading point coordinates
for(int i = 0; i < pt.Count;++i) {
Point3d p = pt[i];
// establish base geometry | cylinder from (x,y,0)
Point3d bot = new Point3d(p.X, p.Y, 0.0);
Circle basee = new Circle(bot, size);
ArcCurve b = new ArcCurve(basee);
// reassign variable due to type error
Curve a = b;
// create extrusion and assign to list
Extrusion ex = Extrusion.Create(b, p.Z, true);
extrusions.Add(ex);
}
// output point list
B = extrusions;
We used C# and millipede to construct a projected visual patch onto the mask as a way to further destruct and reconstruct the burial mask. The orientation of movement is dictated by the original three points of disturbance, and the 2D pattern(Fig 6) was derived from a simplified version of the owl face.
private void RunScript (
List<point3d> pt, </point3d>// original input geometry
double Oxa, double Oya, // initial 1st point of gravity
double Oxb, double Oyb, // initial 2nd point of gravity
double Oxb, double Oyb, // initial 3nd point of gravity
ref object A // output list of coordinates
)
{
// define & initialize variables
Point3d a = new Point3d(Oxa, Oya, 15);
Point3d b = new Point3d(Oxb, Oyb, 15);
Point3d c = new Point3d(Oxc, Oyc, 15);
List<vector3d> vectors = new List<vector3d>();</vector3d></vector3d>
// loop for reading point coordinates
for(int i = 0; i < pt.Count;++i) {
Point3d p = pt[i];
Vector3d v0 = p - Point3d.Origin;
Vector3d xa = a - p;
Vector3d xb = b - p;
Vector3d xc = c - p;
// calculating distance relativity
double pxa = p.DistanceTo(a);
double pxb = p.DistanceTo(b);
double pxc = p.DistanceTo(c);
// compare 3 inputs and allow reaction only to the closest one
if (pxa > pxb && pxa > pxc) {
Vector3d j = xa;
j.Unitize();
vectors.Add(j);
} else if (pxb > pxa && pxb > pxc) {
Vector3d j = xb;
j.Unitize();
vectors.Add(j);
} else {
Vector3d j = xc;
j.Unitize();
vectors.Add(j);
}
}
// output point list
A = vectors;
}
We also experimented with mesh density, smoothness and colors using grasshopper components to see if further distortions of the original form can lead to better results.
Materialize