namespace IntSight.XSight.Geometry; public // Vectors are immutable structures Vector = const record public x, y, z: Double; readonly; constructor(x, y, z: Double); begin Self.x := x; Self.y := y; Self.z := z; end; public property Length: Double => (x.Sqr + y.Sqr + z.Sqr).Sqrt; ensures Result >= 0; method Mirror(axis: Vector): Vector => Self - 2 * Self * axis; requires Self.Length = 1, axis.Length = 1; ensures Result.Length = 1; method Normalize: Vector => using L := Length do if L = 0 then Self else Self / L; ensures Self.Length > 0 -> Result.Length = 1; public static method Combine(f1: Double; v1: Vector; f2: Double; v2: Vector) => new Vector( f1 * v1.x + f2 * v2.x, f1 * v1.y + f2 * v2.y, f1 * v1.z + f2 * v2.z); public <commutative, associative> method+(v1, v2: Vector) => new Vector(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z); method-(v1, v2: Vector) => new Vector(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z); method-(v: Vector) => new Vector(-v.x, -v.y, -v.z); <commutative> method*(v1, v2: Vector): Double => v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; <associative> method^(v1, v2: Vector) => new Vector( v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x * v2.y - v1.y * v2.x); <commutative> method*(v: Vector; f: Double) => new Vector(f * v.x, f * v.y, f * v.z); method/(v: Vector; f: Double) => new Vector(v.x / f, v.y / f, v.z / f); requires f <> 0; operator Explicit(v: Vector): Double => v.Length; end; end.