//Projection returns the projection of test in ref. func Projection(test, ref *v3.Matrix) *v3.Matrix { rr, _ := ref.Dims() Uref := v3.Zeros(rr) Uref.Unit(ref) scalar := test.Dot(Uref) //math.Abs(la)*math.Cos(angle) Uref.Scale(scalar, Uref) return Uref }
//AntiProjection returns a vector in the direction of ref with the magnitude of //a vector A would have if |test| was the magnitude of its projection //in the direction of test. func AntiProjection(test, ref *v3.Matrix) *v3.Matrix { rr, _ := ref.Dims() testnorm := test.Norm(0) Uref := v3.Zeros(rr) Uref.Unit(ref) scalar := test.Dot(Uref) scalar = (testnorm * testnorm) / scalar Uref.Scale(scalar, Uref) return Uref }
//Angle takes 2 vectors and calculate the angle in radians between them //It does not check for correctness or return errors! func Angle(v1, v2 *v3.Matrix) float64 { normproduct := v1.Norm(0) * v2.Norm(0) dotprod := v1.Dot(v2) argument := dotprod / normproduct //Take care of floating point math errors if math.Abs(argument-1) <= appzero { argument = 1 } else if math.Abs(argument+1) <= appzero { argument = -1 } //fmt.Println(dotprod/normproduct,argument) //dotprod/normproduct, dotprod, normproduct,v1.TwoNorm(),v2.TwoNorm()) angle := math.Acos(argument) if math.Abs(angle) <= appzero { return 0.00 } return angle }