{-# LANGUAGE TupleSections #-} module Polyhedra.Geodesic where import Geometry.Data import Geometry.Vector3D import Polyhedra.Data import Data.List import qualified Data.Map as M icosahedronPoints :: [Point3] icosahedronPoints = concat [ [V3 0 one gr, V3 one gr 0, V3 gr 0 one] | one <- [-1,1] , gr <- [negate (1 + sqrt 5)/2, (1 + sqrt 5)/2 ] ] icosohedronFaces :: [[Point3]] icosohedronFaces = map orderFace $ rectEdgeFaces ++ map (map rotTrip) rectEdgeFaces ++ map (map (rotTrip . rotTrip)) rectEdgeFaces ++ addSym negFst (addSym negSnd $ addSym negThd rectCornFace) where rectEdgeFaces = addSym negThd $ addSym negFst rectEdgeFace rectEdgeFace = [[ (gr,1,0) , (gr,negate 1,0) , (1,0,gr) ]] rectCornFace = [[ (gr,1,0) , (0,gr,1) , (1,0,gr) ]] addSym f faces = map (map f) faces ++ faces negFst (x,y,z) = (negate x,y,z) negSnd (x,y,z) = (x,negate y,z) negThd (x,y,z) = (x,y,negate z) rotTrip (x,y,z) = (z,x,y) gr = (1 + sqrt 5) / 2 :: Float orderFace ps = undefined orderAround3 ps -- | Assuming that this works, note that it relies heavily on the ordering of -- faces adjacent to a vertex (clockwise around the vertex) -- and vertices on faces (anticlockwise around center of face). truncate :: Ord a => VF a -> VF (a,a) truncate vf = VF { _vertices = M.fromList . concatMap f $ M.toList vmap } where vmap = _vertices vf f (i, (pos, faces)) = map (g i pos faces) faces g i pos faces (j:_) = ((i,j) , (0.5 *.*.* (pos +.+.+ fst (vmap M.! j)) ,truncFaces i j faces ) ) g _ _ _ _ = undefined truncFaces :: Eq a => a -> a -> [[a]] -> [[(a,a)]] truncFaces v n vss = [ reverse $ map ((v,) . head) (f1:fs) , g (n:f0) ++ [(n,v)] , (n,v) : g (f1 ++ [v]) ] where (f0:f1:fs) = rotateTo ((== n) . head) vss g (x:y:xs) = [(x,y),(y,x)] ++ g (y:xs) g _ = [] rotateTo :: (a -> Bool) -> [a] -> [a] rotateTo p xs = ys ++ zs where (zs,ys) = break p xs facesToVF :: Ord a => [[a]] -> M.Map a [[a]] facesToVF faces = foldr f M.empty vs where vs = nub $ concat faces f v = M.insert v (g v) g v = map (tail . rotateTo (== v)) $ filter (elem v) faces