<> <> <> DIRECTORY Misc3d, Polynomial, Vector3d; Misc3dImpl: CEDAR PROGRAM IMPORTS Polynomial, Vector3d EXPORTS Misc3d ~ BEGIN OPEN Misc3d; <> FrontFacing: PUBLIC PROC [vector: Triple, view: Matrix] RETURNS [BOOL] ~ { RETURN[vector.x*view[0][2]+vector.y*view[1][2]+vector.z*view[2][2] < 0.0]; }; NearestPair: PUBLIC PROC [p0, p1, q: Pair] RETURNS [nearest: NearPair] ~ { n: Pair ~ [p1.x-p0.x, p1.y-p0.y]; nearest.point _ p0; IF n # [0.0, 0.0] THEN { nSq: REAL ~ n.x*n.x+n.y*n.y; ua: Pair ~ [q.x-p0.x, q.y-p0.y]; nearest.alpha _ (ua.x*n.x+ua.y*n.y)/nSq; nearest.point _ SELECT nearest.alpha FROM <= 0.0 => p0, >= 1.0 => p1, ENDCASE => [p0.x+nearest.alpha*n.x, p0.y+nearest.alpha*n.y]; }; }; NearestTriple: PUBLIC PROC [p0, p1, q: Triple] RETURNS [nearest: NearTriple] ~ { n: Triple ~ [p1.x-p0.x, p1.y-p0.y, p1.z-p0.z]; nearest.point _ p0; IF n # [0.0, 0.0, 0.0] THEN { nSq: REAL ~ n.x*n.x+n.y*n.y+n.z*n.z; ua: Triple ~ [q.x-p0.x, q.y-p0.y, q.z-p0.z]; nearest.alpha _ (ua.x*n.x+ua.y*n.y+ua.z*n.z)/nSq; nearest.point _ SELECT nearest.alpha FROM <= 0.0 => p0, >= 1.0 => p1, ENDCASE => [p0.x+nearest.alpha*n.x, p0.y+nearest.alpha*n.y, p0.z+nearest.alpha*n.z]; }; }; IntersectSplineWithPlane: PUBLIC PROC [coeffs: Coeffs, plane: Quad] RETURNS [ret: PlaneIntersection] ~ { a: Triple ~ [coeffs[0][0], coeffs[0][1], coeffs[0][2]]; b: Triple ~ [coeffs[1][0], coeffs[1][1], coeffs[1][2]]; c: Triple ~ [coeffs[2][0], coeffs[2][1], coeffs[2][2]]; d: Triple ~ [coeffs[3][0], coeffs[3][1], coeffs[3][2]]; pln: Triple ~ [plane.x, plane.y, plane.z]; term3: REAL ~ Vector3d.Dot[a, pln]; term2: REAL ~ Vector3d.Dot[b, pln]; term1: REAL ~ Vector3d.Dot[c, pln]; term0: REAL ~ Vector3d.Dot[d, pln]+plane.w; poly: Polynomial.Ref _ Polynomial.Cubic[[term0, term1, term2, term3]]; realRoots: Polynomial.ShortRealRootRec _ Polynomial.CheapRealRoots[poly]; FOR n: NAT IN [0..realRoots.nRoots) DO IF realRoots.realRoot[n] IN [0.0..1.0] THEN { ret.roots[ret.nRoots] _ realRoots.realRoot[n]; ret.nRoots _ ret.nRoots+1; }; ENDLOOP; }; PointProjectedToPlane: PROC [point: Triple, plane: Quad] RETURNS [Triple] ~ { <> normal: Triple ~ [plane.x, plane.y, plane.z]; distance: REAL ~ Vector3d.Dot[point, normal]+plane.w; RETURN[Vector3d.Sub[point, Vector3d.Mul[normal, distance]]]; }; <<>> END.