<commit_before>{-# LANGUAGE RecordWildCards #-}

module OBJ(
    Vertex(..), Vector,
    Face(..), showOBJ,
    normal, unit, follow
    ) where

import Numeric
import qualified Data.Map as Map


data Vertex = Vertex {x, y, z :: Double} deriving (Eq,Ord)

type Vector = Vertex


data Face = Face {verticies :: [Vertex], normals :: [Vector]}

data S = S {vs :: Map.Map Vertex Int, vns :: Map.Map Vector Int}

showOBJ :: [Face] -> [String]
showOBJ = showFaces $ S Map.empty Map.empty
    where
        showFaces s [] = []
        showFaces s (f:fs) = showFace s f $ \s -> showFaces s fs

        showFace s Face{..} k =
            showList showVertex s verticies $ \s ps ->
            showList showNormal s normals $ \s ns ->
            (unwords $ "f" : zipWith (++) ps (ns ++ repeat "")) : k s

        showList showOne s [] k = k s []
        showList showOne s (p:ps) k = showOne s p $ \s i -> showList showOne s ps $ \s is -> k s (i:is)

        showVertex s@S{..} v@Vertex{..} k
            | Just i <- Map.lookup v vs = k s $ show i
            | otherwise = let i = Map.size vs + 1 in
                          (unwords ["v",shw x,shw y,shw z,'#':show i]) :
                          k s{vs = Map.insert v i vs} (show i)

        showNormal s@S{..} vn@Vertex{..} k
            | Just i <- Map.lookup vn vns = k s $ "//" ++ show i
            | otherwise = let i = Map.size vns + 1 in
                          (unwords ["vn",shw x,shw y,shw z, '#':show i]) :
                          k s{vns = Map.insert vn i vns} ("//" ++ show i)


shw x = showFFloat Nothing x ""


normal :: Vertex -> Vertex -> Vertex -> Vertex
normal (Vertex x1 y1 z1) (Vertex x2 y2 z2) (Vertex x3 y3 z3) = Vertex
    ((y2-y1)*(z3-z1) - (y3-y1)*(z2-z1))
    ((z2-z1)*(x3-x1) - (x2-x1)*(z3-z1))
    ((x2-x1)*(y3-y1) - (x3-x1)*(y2-y1))


len :: Vertex -> Double
len (Vertex x y z) = sqrt (sqr x + sqr y + sqr z)
    where sqr v = v * v

unit :: Vertex -> Vertex
unit v@Vertex{..}
    | n == 0 = v
    | otherwise = Vertex (x*n) (y*n) (z*n)
    where n = len v


follow :: [Vertex] -> Vertex
follow vs = Vertex (sum $ map x vs) (sum $ map y vs) (sum $ map z vs)
<commit_msg>Unit vectors must _divide_ by the length, not multiply by it<commit_after>{-# LANGUAGE RecordWildCards #-}

module OBJ(
    Vertex(..), Vector,
    Face(..), showOBJ,
    normal, unit, follow
    ) where

import Numeric
import qualified Data.Map as Map


data Vertex = Vertex {x, y, z :: Double} deriving (Eq,Ord)

type Vector = Vertex


data Face = Face {verticies :: [Vertex], normals :: [Vector]}

data S = S {vs :: Map.Map Vertex Int, vns :: Map.Map Vector Int}

showOBJ :: [Face] -> [String]
showOBJ = showFaces $ S Map.empty Map.empty
    where
        showFaces s [] = []
        showFaces s (f:fs) = showFace s f $ \s -> showFaces s fs

        showFace s Face{..} k =
            showList showVertex s verticies $ \s ps ->
            showList showNormal s normals $ \s ns ->
            (unwords $ "f" : zipWith (++) ps (ns ++ repeat "")) : k s

        showList showOne s [] k = k s []
        showList showOne s (p:ps) k = showOne s p $ \s i -> showList showOne s ps $ \s is -> k s (i:is)

        showVertex s@S{..} v@Vertex{..} k
            | Just i <- Map.lookup v vs = k s $ show i
            | otherwise = let i = Map.size vs + 1 in
                          (unwords ["v",shw x,shw y,shw z,'#':show i]) :
                          k s{vs = Map.insert v i vs} (show i)

        showNormal s@S{..} vn@Vertex{..} k
            | Just i <- Map.lookup vn vns = k s $ "//" ++ show i
            | otherwise = let i = Map.size vns + 1 in
                          (unwords ["vn",shw x,shw y,shw z, '#':show i]) :
                          k s{vns = Map.insert vn i vns} ("//" ++ show i)


shw x = showFFloat Nothing x ""


normal :: Vertex -> Vertex -> Vertex -> Vertex
normal (Vertex x1 y1 z1) (Vertex x2 y2 z2) (Vertex x3 y3 z3) = Vertex
    ((y2-y1)*(z3-z1) - (y3-y1)*(z2-z1))
    ((z2-z1)*(x3-x1) - (x2-x1)*(z3-z1))
    ((x2-x1)*(y3-y1) - (x3-x1)*(y2-y1))


len :: Vertex -> Double
len (Vertex x y z) = sqrt (sqr x + sqr y + sqr z)
    where sqr v = v * v

unit :: Vertex -> Vertex
unit v@Vertex{..}
    | n == 0 = v
    | otherwise = Vertex (x/n) (y/n) (z/n)
    where n = len v


follow :: [Vertex] -> Vertex
follow vs = Vertex (sum $ map x vs) (sum $ map y vs) (sum $ map z vs)

{'fraction_non_alphanumeric': 0.1625661071510692, 'fraction_numerical': 0.016555530006898137, 'mean_word_length': 1.8731836195508587, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2660658', 'n_tokens_mistral': 1686, 'n_tokens_neox': 1630, 'n_words': 558}