A vector is defined as having three dimensions as being represented by an ordered collection of three numbers:   (X, Y, Z).

If you imagine a graph with the   x   and   y   axis being at right angles to each other and having a third,   z   axis coming out of the page, then a triplet of numbers,   (X, Y, Z)   would represent a point in the region,   and a vector from the origin to the point.

Given the vectors:

        A = (a1,  a2,  a3) 
        B = (b1,  b2,  b3) 
        C = (c1,  c2,  c3) 

then the following common vector products are defined:

 The dot product       (a scalar quantity)
  A • B = a1b1   +   a2b2   +   a3b3  
 The cross product       (a vector quantity)
  A x B = (a2b3  -   a3b2,     a3b1   -   a1b3,     a1b2   -   a2b1)  
 The scalar triple product       (a scalar quantity)
  A • (B x C) 
 The vector triple product       (a vector quantity)
  A x (B x C) 


Task

Given the three vectors:

        a = ( 3,    4,    5)
        b = ( 4,    3,    5)
        c = (-5,  -12,  -13)

 Create a named function/subroutine/method to compute the dot product of two vectors.
 Create a function to compute the cross product of two vectors.
 Optionally create a function to compute the scalar triple product of three vectors.
 Optionally create a function to compute the vector triple product of three vectors.
 Compute and display: a • b
 Compute and display: a x b
 Compute and display: a • (b x c), the scalar triple product.
 Compute and display: a x (b x c), the vector triple product.


References

   A starting page on Wolfram MathWorld is   Vector Multiplication .
   Wikipedia   dot product. 
   Wikipedia   cross product. 
   Wikipedia   triple product.


Related tasks

   Dot product
   Quaternion type


class Vector3D {
    construct new(x, y, z) {
        if (x.type != Num  || y.type != Num || z.type != Num)  Fiber.abort("Arguments must be numbers.")
        _x = x
        _y = y
        _z = z
    }
 
    x { _x }
    y { _y }
    z { _z }
 
    dot(v) {
        if (v.type != Vector3D) Fiber.abort("Argument must be a Vector3D.")
        return _x * v.x + _y * v.y + _z * v.z
    }
 
    cross(v) {
        if (v.type != Vector3D) Fiber.abort("Argument must be a Vector3D.")
        return Vector3D.new(_y*v.z - _z*v.y, _z*v.x - _x*v.z, _x*v.y - _y*v.x)
    }
 
    scalarTriple(v, w) {
        if ((v.type != Vector3D) || (w.type != Vector3D)) Fiber.abort("Arguments must be Vector3Ds.")
        return this.dot(v.cross(w))
    }
 
    vectorTriple(v, w) {
        if ((v.type != Vector3D) || (w.type != Vector3D)) Fiber.abort("Arguments must be Vector3Ds.")
        return this.cross(v.cross(w))
    }
 
    toString { [_x, _y, _z].toString }
}
 
var a = Vector3D.new(3, 4, 5)
var b = Vector3D.new(4, 3, 5)
var c = Vector3D.new(-5, -12, -13)
System.print("a = %(a)")
System.print("b = %(b)")
System.print("c = %(c)")
System.print()
System.print("a . b     = %(a.dot(b))")
System.print("a x b     = %(a.cross(b))")
System.print("a . b x c = %(a.scalarTriple(b, c))")
System.print("a x b x c = %(a.vectorTriple(b, c))")