{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeInType #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE PartialTypeSignatures #-} module HCad.Part.Extensions where import HCad.Part import Algebra.Linear import Algebra.Classes hiding (normalize) import Algebra.Category import Prelude hiding (Num(..),(/),divMod,div,recip,fromRational, (.), mod, id) -- | Extrude a shape along a givent segment. The y axis of the shape -- will align with the upwards direction given. This function may -- crash if the segment is itself too well aligned with the segment. extrudeAlongSegment :: (Show a,Floating a, Field a) => Part xs V2' a -- ^ shape -> V3 a -- ^ upwards direction -> (V3 a, V3 a) -- ^ segment -> Part (SimpleFields '[Nadir,Zenith] ++ xs) V3' a extrudeAlongSegment shape upDir (start,end) = translate start $ rotate r $ center nadir $ extrude l shape where r = transpose $ Mat (fromEuclid <$> (V3' x' (x' × z') z')) l = norm d d = end-start z' = normalize d x' = normalize (upDir × z') -- >>> main -- | Apply 'extrudeAlongSegment' on several segments extrudeAlongSegments :: (Show a, Floating a, Field a) => Part xs V2' a -> V3 a -> [(V3 a, V3 a)] -> Part '[] V3' a extrudeAlongSegments shape upDir = unions . map (extrudeAlongSegment shape upDir)