DIRECTORY CastRays, CSG, DisplayList3d, IO, Polynomial, Rope, SV2d, SV3d, SVModelTypes, SVRayTypes, SVSceneTypes, TFI3d; CatastropheClassImpl: PROGRAM IMPORTS CastRays, CSG, DisplayList3d, IO, Polynomial, TFI3d EXPORTS = BEGIN Camera: TYPE = SVModelTypes.Camera; Point2d: TYPE = SV2d.Point2d; Point3d: TYPE = SV3d.Point3d; Shape: TYPE = SVSceneTypes.Shape; Vector: TYPE = SV3d.Vector; Assembly: TYPE = SVSceneTypes.Assembly; Classification: TYPE = SVRayTypes.Classification; Composite: TYPE = SVRayTypes.Composite; MasterObject: TYPE = SVSceneTypes.MasterObject; MasterObjectClass: TYPE = SVSceneTypes.MasterObjectClass; MasterObjectClassList: TYPE = SVSceneTypes.MasterObjectClassList; -- LIST OF MasterObjectClass Primitive: TYPE = SVRayTypes.Primitive; Ray: TYPE = SVRayTypes.Ray; globalPoly: Polynomial.Ref; catastropheClass: MasterObjectClass; CatastropheCast: PUBLIC PROC [cameraPoint: Point2d, localRay: Ray, masterObject: REF ANY, prim: Primitive] RETURNS [class: Classification] = { realRoots: Polynomial.ShortRealRootRec; -- optional x0, x1, y0, y1, z0, z1: REAL; a3,a2,a1,a0: REAL; p: Point3d; d: Vector; onSection, bool1, bool2, bool3: BOOL; x, y, z: REAL; j: NAT; CatastropheGrad: PROC [x, y, z: REAL] RETURNS [Vector] ~ { gradx, grady, gradz: REAL; gradx _ - z; grady _ 1; gradz _ 3. * z * z - x; RETURN [[gradx, grady, gradz]]; }; class _ CastRays.GetClassFromPool[]; [p, d] _ CSG.GetLocalRay[localRay]; -- p is base point, d is directiona x0 _ p[1]; x1 _ d[1]; y0 _ p[2]; y1 _ d[2]; z0 _ p[3]; z1 _ d[3]; a3 _ z1 * z1 * z1; a2 _ 3. * z1 * (z0 * z1 - x1 ); a1 _ 3. * z0 * z0 * z1 - x0 * z1 - x1 * z0 + y1; a0 _ z0 * ( z0 * z0 - x0) + y0 ; realRoots _ PositiveRoots[a3,a2,a1,a0]; onSection _ FALSE; j _ 1; WHILE NOT onSection AND j <= realRoots.nRoots DO x _ x0 + realRoots.realRoot[j-1]*x1; y _ y0 + realRoots.realRoot[j-1]*y1; z _ z0 + realRoots.realRoot[j-1]*z1; bool1 _ x > 0.0; bool2 _ 27. * y * y - 4. * x * x * x < 0.0 ; bool3 _ 3. * z * z - x < 0.0; onSection _ bool1 AND bool2 AND bool3; -- apply the defining formula for cell (3,3,4) j _ j + 1; ENDLOOP; IF onSection THEN { class.count _ 1; class.params[1] _ realRoots.realRoot[0]; class.surfaces[1] _ NIL; class.classifs[1] _ FALSE; class.classifs[2] _ TRUE; class.primitives[1] _ prim; class.normals[1] _ CatastropheGrad[x, y, z]; } ELSE { class.count _ 0; class.classifs[1] _ FALSE; }; }; PositiveRoots: PROCEDURE [a3, a2, a1, a0: REAL] RETURNS [rootArray: Polynomial.ShortRealRootRec] = { i: NAT _ 1; globalPoly[3] _ a3; -- optional globalPoly[2] _ a2; -- optional globalPoly[1] _ a1; -- optional globalPoly[0] _ a0; -- optional rootArray _ Polynomial.CheapRealRoots[globalPoly]; -- optional IF rootArray.nRoots = 0 THEN RETURN; WHILE i <= rootArray.nRoots DO IF rootArray.realRoot[i-1] <= 0 THEN { FOR j: NAT IN [i..rootArray.nRoots-1] DO rootArray.realRoot[j-1] _ rootArray.realRoot[j]; ENDLOOP; rootArray.nRoots _ rootArray.nRoots - 1; } ELSE {i _ i + 1}; ENDLOOP; }; MakeMasterObject: PROC [name: Rope.ROPE] RETURNS [mo: MasterObject] = { mainBody: REF ANY _ NIL; lineBody: REF ANY _ NIL; shadeBody: REF ANY _ lineBody; rayCastBody: REF ANY _ NIL; mo _ DisplayList3d.CreateMasterObject[name, catastropheClass, mainBody, lineBody, shadeBody, rayCastBody]; }; CatastropheFileout: PUBLIC PROC [f: IO.STREAM, mo: MasterObject] = { f.PutChar[IO.TAB]; f.PutF["data: procedural\n"]; }; CatastropheFilein: PUBLIC PROC [f: IO.STREAM, name: Rope.ROPE] RETURNS [mo: MasterObject] = { TFI3d.ReadRope[f, "data: procedural"]; TFI3d.ReadBlank[f]; mo _ MakeMasterObject[name]; }; Init: PROC = { catastrophe: MasterObject; globalPoly _ Polynomial.Cubic[[0,0,0,0]]; catastropheClass _ DisplayList3d.RegisterMasterObjectClass[ "catastrophe", CatastropheFilein, CatastropheFileout, DisplayList3d.NoOpFileoutPoly, CatastropheCast, DisplayList3d.NoOpRayCastNoBBoxes, DisplayList3d.NoOpRayCastBoundingSpheres, DisplayList3d.NoOpBoundHedron, DisplayList3d.NoOpPreprocess, DisplayList3d.NoOpLineDraw, DisplayList3d.NoOpNormalsDraw, DisplayList3d.NoOpCountPlanarSurfaces, DisplayList3d.NoOpGetPlanarSurfaces, DisplayList3d.NoOpDrawPlanarSurface, DisplayList3d.NoOpDrawSubBoxes, DisplayList3d.NoOpDrawSubSpheres]; catastrophe _ MakeMasterObject["catastrophe"]; DisplayList3d.RegisterMasterObject[catastrophe]; }; Init[]; END. βFile: CatastropheClassImpl.mesa Last edited by Bier on January 10, 1985 5:22:13 pm PST Author: Dennis Arnon and Eric Bier on January 17, 1985 3:42:30 pm PST RAY CASTING TYPES The Catastrophe surface is: 3 F(x,y,z) = z - x z + y 1/17/85 - modified to only do cell (3,3,4) of the cad. catastropheData: CatastropheRec; realRoots: ARRAY[0..3] OF REAL; realRootsOneOrigin: ARRAY[1..4] OF REAL; rootCount: NAT; catastropheData _ NARROW[catastropheRec]; The result of substituting F, x: x1 * t + x0, y: y1 * t + y0, z: z1 * t + z0; in Macsyma: 3 3 2 2 2 2 3 (d3) t z1 + 3 t z0 z1 + 3 t z0 z1 - t x1 z1 - t x0 z1 + z0 - t x1 z0 - x0 z0 + t y1 + y0 To normalize, divide by norm. (I won't do this since the lighting model normalizes anyway) Use only the positive roots. [realRootsOneOrigin, rootCount] _ Roots.RealQuartic[a4, a3, a2, a1, a0]; -- no possibility of applicability since catastrophe surface is cubic realRoots[0] _ realRootsOneOrigin[1]; realRoots[1] _ realRootsOneOrigin[2]; realRoots[2] _ realRootsOneOrigin[3]; realRoots[3] _ realRootsOneOrigin[4]; Catastrophes can be built from scratch. Κ#˜Ihead1™J™6J™EJ˜šΟk ˜ Jšœ˜ J˜Jš œ˜J˜J˜ J˜J˜J˜Jšœ ˜ Jšœ ˜ Jšœ ˜ Jšœ˜J˜—šœ˜Jšœœœ˜;Jšœ˜ —Jš˜J˜Iprocšœœ˜#Lšœ œ˜Lšœ œ˜L˜Lšœœ˜!Lšœœ˜L˜Lšœ™˜Lšœ œ˜'Lšœœ˜2Lšœ œ˜'Lšœœ˜/Lšœœ"˜9Lšœœ'Οc˜^Lšœ œ˜'Lšœœ˜L˜Jšœ˜Jšœ$˜$J˜—J˜š Οnœœœ5œœ˜jšœ˜#J˜JšΟf™Jš x™xJ™—J™ Jšœ)ž ˜4J™J™(J™J˜Jšœ œ˜J˜ J˜ Jšœ œ˜%Jšœ œ˜Jšœœ˜šŸœœ œœ ˜:Jšœœ˜J˜ J˜ J˜Jšœ˜J˜—J˜Jšœ$˜$Jšœœ™)Jšœ œž#˜GJšœ˜Jšœ˜Jšœ˜˜J˜J™J™J™Jš 4™4J™J™ J™Jš Δ™Δ—˜J˜—š ˜J˜J˜—š ˜J˜J˜—š 0˜0J˜J˜—Jš  ˜ J˜J˜Jšœ'˜'Jšœ œ ˜šœœ œ˜0Jšœ$˜$Jšœ$˜$Jšœ$˜$Jšœ˜J˜,J˜Jšœœœ ž.˜VJ˜ Jš˜—šœ œ˜Jšœ˜Jšœ(˜(Jšœ˜Jšœœœ˜6Jšœ˜Jšœ,˜,J™[J˜—š˜Jšœ˜Jšœœ˜Jšœ˜—˜J˜——šŸ œ œœœ-˜dJ™Lšœœ˜ Jšœž ˜ Jšœž ˜ Jšœž ˜ Jšœž ˜ Lšœ3ž ˜?Lšœ™JšœK™KJšœL™LLšœœœ˜$šœ˜šœœ˜&šœœœ˜(Lšœ0˜0—Lšœ˜Lšœ(˜(L˜—Lšœ ˜—Lšœ˜Jšœ˜J˜—šŸœœ œœ˜GLšœ œœœ˜Lšœ œœœ˜Lšœ œœ ˜Lšœ œœœ˜Lšœj˜jLšœ˜L˜—š Ÿœœœœœ˜DLšœ'™'Lšœ œœ˜Lšœ˜Lšœ˜—šŸœœœœœ œœ˜]Lšœ&˜&Lšœ˜Lšœ˜L˜—šŸœœ˜Lšœ˜Jšœ)˜)šœ;˜;Lšœ˜LšŸœ˜LšŸœ˜Lšœ˜LšΟbœ˜Lšœ"˜"Lšœ)˜)Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ&˜&Lšœ$˜$Lšœ$˜$Lšœ˜Lšœ"˜"—L˜Lšœ.˜.Lšœ0˜0L˜L˜—Lšœ˜L˜Lšœ˜˜J˜J˜—J˜—…—θν