<> <> <> DIRECTORY Clip3d, Draw2d, Draw3d, Imager, Matrix3d, Spline3d, Rope, Vector3d; Draw3dImpl: CEDAR PROGRAM IMPORTS Clip3d, Draw2d, Imager, Matrix3d, Spline3d EXPORTS Draw3d ~ BEGIN Context: TYPE ~ Imager.Context; Pair: TYPE ~ Vector3d.Pair; Triple: TYPE ~ Vector3d.Triple; Quad: TYPE ~ Vector3d.Quad; Matrix: TYPE ~ Matrix3d.Matrix; Coeffs: TYPE ~ Spline3d.Coeffs; Bezier: TYPE ~ Spline3d.Bezier; Mark: PUBLIC PROC [p: Triple, context: Context, m: Matrix, type: Draw2d.MarkType _ cross, label: Rope.ROPE _ NIL] ~ { IF type # none THEN { q: Quad _ Matrix3d.TransformH[p, m]; IF q.z+q.w >= 0.0 THEN { pp: Pair _ [q.x/q.w, q.y/q.w]; Draw2d.Mark[context, pp, type]; IF label # NIL THEN Draw2d.Label[context, pp, label]; }; }; }; PP: PUBLIC PROC [p0, p1: Triple, c: Context, m: Matrix, type: Draw2d.DrawType _ solid] ~ { c0, c1: Pair; IF Matrix3d.HasPerspective[m] THEN { off: BOOL; [c0, c1, off] _ Clip3d.NearH[Matrix3d.TransformH[p0, m], Matrix3d.TransformH[p1, m]]; IF NOT off THEN Draw2d.Draw[c, c0, c1, type]; } ELSE { c0 _ Matrix3d.TransformD[p0, m]; c1 _ Matrix3d.TransformD[p1, m]; Draw2d.Draw[c, c0, c1, type]; }; }; PV: PUBLIC PROC [p, v: Triple, label: Rope.ROPE _ NIL, context: Context, m: Matrix, mark: Draw2d.MarkType _ none, scale: REAL _ 0.2] ~ { c0, c1, d: Pair; pp: Triple _ [p.x+v.x, p.y+v.y, p.z+v.z]; IF Matrix3d.HasPerspective[m] THEN { off: BOOL; [c0, c1, off] _ Clip3d.NearH[Matrix3d.TransformH[p, m], Matrix3d.TransformH[pp, m]]; IF off THEN RETURN; IF mark # none THEN Mark[p, context, m, mark]; } ELSE { c0 _ Matrix3d.TransformD[p, m]; c1 _ Matrix3d.TransformD[pp, m]; IF mark # none THEN Draw2d.Mark[context, c0, mark]; }; d _ [c1.x-c0.x, c1.y-c0.y]; c1 _ [c0.x+scale*d.x, c0.y+scale*d.y]; Draw2d.Arrow[context, c1, c0]; IF label # NIL THEN Draw2d.Label[context, c1, label]; }; V: PUBLIC PROC [v: Triple, name: Rope.ROPE _ NIL, context: Context, m: Matrix] ~ { xv: Triple _ Matrix3d.TransformVec[v, m]; Draw2d.Solid[context, [m[3][0], m[3][1]], [xv.x, xv.y]]; Draw2d.Label[context, [xv.x, xv.y], name]; }; Axes: PUBLIC PROC [context: Context, m: Matrix] ~ { PV[[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], "X", context, m]; PV[[0.0, 0.0, 0.0], [0.0, 1.0, 0.0], "Y", context, m]; PV[[0.0, 0.0, 0.0], [0.0, 0.0, 1.0], "Z", context, m]; }; <> <<>> DrawCurve: PUBLIC PROC [c: Coeffs, context: Context, m: Matrix _ NIL] ~ { IF c # NIL THEN { persp: BOOL _ Matrix3d.HasPerspective[m]; xc: Coeffs _ IF m = NIL THEN c ELSE Matrix3d.Mul[c, m]; nSegs: INTEGER _ Spline3d.Resolution[xc, 1.0]; dif: Coeffs _ Spline3d.FwdDif[xc, nSegs]; nCoords: NAT _ IF persp THEN 3 ELSE 1; p0, p1: Pair _ [dif[0][0], dif[0][1]]; q0, q1: Quad _ [dif[0][0], dif[0][1], dif[0][2], dif[0][3]]; FOR i: INTEGER IN[0..nSegs) DO IF persp THEN q1 _ [q0.x+dif[1][0], q0.y+dif[1][1], q0.z+dif[1][2], q0.w+dif[1][3]] ELSE p1 _ [p0.x+dif[1][0], p0.y+dif[1][1]]; FOR j: INTEGER IN[0..nCoords] DO dif[1][j] _ dif[1][j]+dif[2][j]; dif[2][j] _ dif[2][j]+dif[3][j]; ENDLOOP; IF persp THEN { c0, c1: Pair; offScreen: BOOL; [c0, c1, offScreen] _ Clip3d.NearH[q0, q1]; IF NOT offScreen THEN Draw2d.Solid[context, c0, c1]; q0 _ q1; } ELSE { Draw2d.Solid[context, p0, p1]; p0 _ p1; }; ENDLOOP; }; }; DotCurve: PUBLIC PROC [c: Coeffs, context: Context, m: Matrix _ NIL] ~ { persp: BOOL _ Matrix3d.HasPerspective[m]; xc: Coeffs _ IF m = NIL THEN c ELSE Matrix3d.Mul[c, m]; nSegs: INTEGER _ 4*Spline3d.Resolution[xc, 1.0]; dif: Coeffs _ Spline3d.FwdDif[xc, nSegs]; nCoords: NAT _ IF persp THEN 3 ELSE 1; p: Pair _ [dif[0][0], dif[0][1]]; q: Quad _ [dif[0][0], dif[0][1], dif[0][2], dif[0][3]]; FOR i: INTEGER IN[0..nSegs) DO IF persp THEN {IF q.w+q.z >= 0.0 THEN Imager.MaskRectangle[context, [q.x/q.w, q.y/q.w, 1, 1]]} ELSE Imager.MaskRectangle[context, [p.x, p.y, 1, 1]]; IF persp THEN q _ [q.x+dif[1][0], q.y+dif[1][1], q.z+dif[1][2], q.w+dif[1][3]] ELSE p _ [p.x+dif[1][0], p.y+dif[1][1]]; FOR j: INTEGER IN[0..nCoords] DO dif[1][j] _ dif[1][j]+dif[2][j]; dif[2][j] _ dif[2][j]+dif[3][j]; ENDLOOP; ENDLOOP; }; DrawBezierPolygon: PUBLIC PROC [b: Bezier, context: Context, m: Matrix _ NIL, type: Draw2d.DrawType _ solid, close: BOOL _ FALSE] ~ { PP[b.b0, b.b1, context, m, type]; PP[b.b1, b.b2, context, m, type]; PP[b.b2, b.b3, context, m, type]; IF close THEN PP[b.b0, b.b3, context, m, type]; }; END. <> <> <<>> <> <> <> <> <<>> <> <> <> <<}>> <> < a1 THEN RETURN[c0, c1, TRUE];>> <<>> <> <> <> <> <<};>> <> <> <<[c0, c1, off] _ ClipZ[p0, p1, -focalLength+0.01];>> <> <> <> <> <<};>> <<};>> <<>>