1 module Solve(solve,alt) where
    2 import Numbers
    3 import Vectors
    4 import EdgePlate
    5 -- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    6 -- Mark R: solving sets of equations
    7 -- ignore the z coordinate
    8 -- lambda*proj v1 + mu*proj v2 = proj w =>
    9 -- solve v1 v2 w yields the (empty or singleton) list of solutions (lambda,mu)
   10 
   11 solve :: Vector -> Vector -> Vector -> [(Number,Number)]
   12 solve v1 v2 w =
   13         let determinant = z (v1*v2) in
   14         if determinant==0
   15         then []
   16         else [( z(w*v2) / determinant, z(v1*w) / determinant)]
   17 
   18 -- The point (x(p), y(p), alt ls p) lies in the plate in which ls lies.
   19 -- Hence proj p == proj (s(l1)+lambda*h(l1)+mu*h(l2) ) so use solve
   20 -- lambda*proj h(l1) + mu*proj h(l2) = proj (p-s(l1))
   21 
   22 alt :: Plate -> Vector -> Number
   23 alt (Plt _ (l1:l2:_)) p =
   24         z( sl1 + lambda `mulv` hl1 + mu `mulv` hl2)
   25         where
   26         sl1 = s(l1) ; hl1 = h(l1) ; hl2 = h(l2)
   27         [(lambda,mu)] = solve hl1 hl2 (p-sl1)
   28         -- this is always solvable
   29