<> <> <> 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] = { <> << 3 F(x,y,z) = z - x z + y 1/17/85 - modified to only do cell (3,3,4) of the cad.>> <<>> <> 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]; <> <<>> <<>> << 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 >> 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 <<[realRootsOneOrigin, rootCount] _ Roots.RealQuartic[a4, a3, a2, a1, a0]; -- no possibility of applicability since catastrophe surface is cubic>> <> <> 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.