COTARD DELUSION

Burial Mask: Surface Manipulation, Discretization and Curve Processing


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 methodology of this interactive system, built in Rhino-Grashopper via C#, includes surface manipulation, discretization and curve processing. The result render of the interaction is a responsive “burial mask " adapt to user input pictures/models in metaphorical setting.
KEYWORDS
proceedings; imaging; design computation; parametric design; digital media; user interface; interactive design; data visualization; digital modeling; digital fabrication; motion graphics

Surface Manipulation, Discretization and Curve Processing
FOR INTERACTIVE VISUALS

‍

1 CONCEPT: Cotard Delusion

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.

Figure 1: Manipulation of the scanned owl head model from GrabCAD

‍

2 METHODology

2.1     Visual sketching and prototyping using height map generated from Rhino and visual programming in p5.js editor

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.

Figure 2: Generation steps

‍‍

2.2     Workflow

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#.

Figure 2: Workflow map

‍‍

2.3 Surface Manipulation Initial

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;

Figure 3: Axon output     
2.4     Deformation and Resculpting

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.

Figure 4:Deformation Result for User Interaction
‍‍2.5 Descreization

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;

Figure 5: Cylinder attempt

‍‍

‍2.6     Surface pattern  | Colorization   

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;
}

Figure 6: Pattern Array based on vertices
Figure 7: Pattern array adapted to user input

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.

Figure 8: Colorization on height information
Figure 9: Grasshopper prototype

Materialize

Figure 10: Final Colorization
‍
Figure 7: Adaptive color to user input

Yiqi, designer, technologist, artist.

about ME
CONTACT ME
⇑ TOPBACK TO WORKS


Have a good day !
HOME
Contacts
WA, USA
vanyiqi@gmail.com
sirrandom
Follow
/Long dream stretches, because of you.
Copyright © 2022 Yiqi Zhao. All rights reserved. 0_0