triangulate :: Vector (V3 Float) -> Vector (V3 Float, V3 Float, V3 Float)
triangulate vs
  | V.length vs < 3 = V.empty
  | colinearAll vs = V.empty
  | otherwise =
      fmap (\(v1, v2, v3) -> (fromV2 v1, fromV2 v2, fromV2 v3))
    . V.fromList . D.triangulate . V.toList . fmap toV2 $ v2snorm
    where
    plane = planeFromPoints (V.unsafeIndex vs 0) (V.unsafeIndex vs 1) (V.unsafeIndex vs 2)
    (denormVec, v2snorm) = normVecs v2s
    v2s = planeProject plane <$> vs
    toV2 (V2 x y) = Vec.Vector2 (realToFrac x) (realToFrac y)
    fromV2 (Vec.Vector2 x y) = planePoint plane . denormVec $ V2 (realToFrac x) (realToFrac y)
triangulate :: Vector (V3 Float) -> Vector (V3 Float, V3 Float, V3 Float)
triangulate vs
  | V.length vs < 3 = V.empty
  | colinearAll vs = V.empty
  | otherwise =
      fmap (\(v1, v2, v3) -> (fromV2 v1, fromV2 v2, fromV2 v3))
    . V.fromList . D.triangulate . V.toList . fmap toV2 $ v2snorm
    where
    plane = planeFromPoints (V.unsafeIndex vs 0) (V.unsafeIndex vs 1) (V.unsafeIndex vs 2)
    (denormVec, v2snorm) = normVecs v2s
    v2s = planeProject plane <$> vs
    toV2 (V2 x y) = Vec.Vector2 (realToFrac x) (realToFrac y)
    fromV2 (Vec.Vector2 x y) = planePoint plane . denormVec $ V2 (realToFrac x) (realToFrac y)
triangulate vs
  | V.length vs < 3 = V.empty
  | colinearAll vs = V.empty
  | otherwise =
      fmap (\(v1, v2, v3) -> (fromV2 v1, fromV2 v2, fromV2 v3))
    . V.fromList . D.triangulate . V.toList . fmap toV2 $ v2snorm
    where
    plane = planeFromPoints (V.unsafeIndex vs 0) (V.unsafeIndex vs 1) (V.unsafeIndex vs 2)
    (denormVec, v2snorm) = normVecs v2s
    v2s = planeProject plane <$> vs
    toV2 (V2 x y) = Vec.Vector2 (realToFrac x) (realToFrac y)
    fromV2 (Vec.Vector2 x y) = planePoint plane . denormVec $ V2 (realToFrac x) (realToFrac y)