MODULE Spring; CONST Length = 100, K = 10; (* "Length" is the natural length of a spring in its relaxed state. "K" is the force constant of the spring. According to Hooke's law, the force "F" exerted by a spring stretched a distance "dx" is given by the equation: | | F = - K * dx | This equation also applies when "dx" is negative, that is, when the spring is compressed. *) CONST EndLen = 30, Width = 20; FUNC d = Dist(p, q) IS d = Geometry.Length((p, q)) END; PRIVATE PROC Coil(a, b) IS IF VAR d ~ (0.12, 0.5) REL (a, b), e ~ (0.38, -0.5) REL (a, b), f ~ (0.62, 0.5) REL (a, b), g ~ (0.88, -0.5) REL (a, b), i = (0.11879119, 0) REL (a, b), j = (0.37709966, 0) REL (a, b), k = (0.61871946, 0) REL (a, b), l = (0.87736887, 0) REL (a, b) IN Width = Dist(i, d) AND (i, d) CONG (j, e) AND (a, b) PARA (d, f) AND (a, b) PARA (e, g) AND Angle.Right(a, i, d) AND Angle.Right(a, j, e) AND Angle.Right(a, k, f) AND Angle.Right(a, l, g) -> SAVE PS IN PS.MoveTo(a); PS.LineTo(d); PS.LineTo(e); PS.LineTo(f); PS.LineTo(g); PS.LineTo(b); PS.SetRGB(1, 0, 0); PS.Stroke() END END FI END; FUNC c = F(a, b) IS c = -K * (Dist(a, b) - Length) END; (* "c" is the force of the spring with endpoints "a" and "b". *) PRIVATE PROC WriteF(a, b) IS IF VAR c = (0.5, 0) REL (a, b), d ~ (0.5000001, 0.143312) REL (a, b) IN Angle.RightGeometry(a, c, d) AND Width + 10 = Dist(c, d) -> PS.Type(d, Text.FromNum(F(a, b), 2)) END FI END; PROC Draw(a, b) IS IF VAR c ~ (0.3052813, 0) REL (a, b), d ~ (0.6947187, 0) REL (a, b) IN Geometry.Colinear(a, c, b) AND Geometry.Colinear(a, d, b) AND (a, c) CONG (d, b) AND EndLen = Dist(a, c) -> SAVE PS IN PS.MoveTo(a); PS.LineTo(c); PS.MoveTo(d); PS.LineTo(b); PS.SetWidth(3); PS.Stroke(); Coil(c, d) END; WriteF(a, b) END FI END; FUNC fv = FV(a, b) IS fv = R2.Times(F(a, b), R2.Normalize(R2.Minus(b, a))) END; (* "fv" is the force vector at "a" due to the spring between "a" and "b". *) PRED Junction2(a, b, c) IS (E fab ~ (0, 0), fac ~ (0, 0) :: fab = FV(a, b) AND fac = FV(a, c) AND R2.Plus(fab, fac) = (0, 0)) END; PRED Junction3(a, b, c, d) IS (E fab ~ (0, 0), fac ~ (0, 0), fad ~ (0, 0) :: R2.Plus(FV(a, b), R2.Plus(FV(a, c), FV(a, d))) = (0, 0)) END;