CONST WidthFactor = 2000, CubeSize = 100; PROC DrawCube2D(dist, p000, p100, p010, p001, p110, p011, p101, p111) IS SAVE PS IN PS.SetEndStyle(PS.RoundEnds); PS.SetJointStyle(PS.RoundJoints); PS.SetWidth(WidthFactor / dist); PS.MoveTo(p001); PS.LineTo(p101); PS.LineTo(p111); PS.LineTo(p011); PS.Close(); Line.Draw(p100, p101); Line.Draw(p010, p011); Line.Draw(p110, p111); Line.Draw(p110, p100); Line.Draw(p110, p010); PS.Stroke(); SAVE PS IN PS.SetColor(Color.Red); Arrow.Straight(p000, p100) END; SAVE PS IN PS.SetColor(Color.Green); Arrow.Straight(p000, p010) END; SAVE PS IN PS.SetColor(Color.Blue); Arrow.Straight(p000, p001) END END END; PROC DrawCube(org, camLoc, dist) IS IF VAR D = CubeSize, P000 = [0, 0, 0], p000 ~ (200, 200), P100 ~ [200, 0, 0], p100 ~ (187.3, 185.3), P010 ~ [0, 200, 0], p010 ~ (221, 193.9), P001 ~ [0, 0, 200], p001 ~ (200, 221.2), P110 ~ [200, 200, 0], p110 ~ 0, P011 ~ [0, 200, 200], p011 ~ 0, P101 ~ [200, 0, 200], p101 ~ 0, P111 ~ [200, 200, 200], p111 ~ 0 IN P100 = [D, 0, 0] AND P010 = [0, D, 0] AND P001 = [0, 0, D] AND P110 = [D, D, 0] AND P011 = [0, D, D] AND P101 = [D, 0, D] AND P111 = [D, D, D] AND p000 = Proj3D.Project(P000, org, camLoc) AND p100 = Proj3D.Project(P100, org, camLoc) AND p010 = Proj3D.Project(P010, org, camLoc) AND p001 = Proj3D.Project(P001, org, camLoc) AND p110 = Proj3D.Project(P110, org, camLoc) AND p011 = Proj3D.Project(P011, org, camLoc) AND p101 = Proj3D.Project(P101, org, camLoc) AND p111 = Proj3D.Project(P111, org, camLoc) -> DrawCube2D(dist, p000, p100, p010, p001, p110, p011, p101, p111) END FI END; CONST MinDist = 200, MaxDist = 1000, ToDegrees = 180 / Math.Pi; FUNC x = MapDist(t) IS x = MinDist + t * (MaxDist - MinDist) END; FUNC theta = MapDir(t) IS theta = (t - 0.5) * 2 * Math.Pi END; FUNC theta = MapElev(t) IS theta = (t - 0.5) * Math.Pi END; FUNC res = DirVector(t1, t2) IS (E k = COS(t2) :: res = [k * COS(t1), k * SIN(t1), SIN(t2)]) END; (* Return a vector in R3 for the direction corresponding to a direction in the XY plane of t1 radians (t1 = 0 corresponds to a direction along the X axis) and an elevation above the XY plane of t2 radians. *) PROC VertTick(a) IS IF VAR b ~ R2.Plus(a, (0, 3)), c ~ R2.Plus(a, (0, -3)) IN a = Geometry.Mid(b, c) AND b VER a AND 5 = Geometry.Dist(a, b) -> PS.MoveTo(b); PS.LineTo(c) END FI END; UI PointTool(VertTick); PROC SlideGuide(a, b) IS PS.Save(); VertTick(a); VertTick(b); PS.MoveTo(a); PS.LineTo(b); PS.SetWidth(2); PS.Stroke(); PS.Restore() END; UI PointTool(SlideGuide); PROC Label(a, b, txt) IS Type.C(R2.PlusY(Geometry.Mid(a, b), 9), txt); SlideGuide(a, b) END; UI TextTool(Label); PROC LabelVal(a, c, val) IS SAVE PS IN VAR b = Geometry.HorVer(a, c) IN VertTick(b); PS.SetWidth(2); PS.Stroke(); TypeLinesC.North(R2.PlusY(b, -4), Unparse.Value(val)) END END END; PROC Cmd0() IS IF VAR origin = (-24.993603, -204.03358), a = (-168.13878, 232.09769), b ~ (175.7126, 232.09769), c = (-120.42372, 227.54675), d ~ (-168.13878, 164.59215), e ~ (175.7126, 164.59215), f = (-114.36466, 152.45633), g ~ (-168.13878, 97.08662), h = (175.7126, 97.08662), i = (-46.957676, 81.15834), dist ~ 311.0132, theta1 ~ -2.15898, theta2 ~ -0.46362716, dir ~ [-0.4962787, -0.74412626, -0.4471953], camLoc ~ [-154.34923, -231.4331, -139.08365] IN dist = MapDist(Rel.InvX(c, a, b)) AND theta1 = MapDir(Rel.InvX(f, d, e)) AND theta2 = MapElev(Rel.InvX(i, g, h)) AND dir = DirVector(theta1, theta2) AND camLoc = R3.Times(dist, R3.Normalize(dir)) AND b = Geometry.HorVer(a, h) AND g = Geometry.HorVer(h, a) AND d = Geometry.Mid(a, g) AND e = Geometry.Mid(b, h) -> Label(a, b, "Camera Distance"); Label(d, e, "Z-Rotation"); Label(g, h, "Elevation"); LabelVal(a, c, dist); LabelVal(d, f, theta1 * ToDegrees); LabelVal(g, i, theta2 * ToDegrees); DrawCube(origin, camLoc, dist) END FI END;