strictly formatting changes
This commit is contained in:
parent
b5ae16ac59
commit
b4ee69cd7f
8 changed files with 55 additions and 82 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
packages:
|
packages:
|
||||||
./
|
./
|
||||||
|
|
||||||
|
profiling: True
|
||||||
-- package repa
|
-- package repa
|
||||||
-- ghc-options: -fincomplete-uni-patterns
|
-- ghc-options: -fincomplete-uni-patterns
|
||||||
|
|
|
||||||
16
flake.lock
generated
16
flake.lock
generated
|
|
@ -91,7 +91,6 @@
|
||||||
"flake-utils": "flake-utils",
|
"flake-utils": "flake-utils",
|
||||||
"haskell-flake": "haskell-flake",
|
"haskell-flake": "haskell-flake",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"systems": "systems_2",
|
|
||||||
"treefmt-nix": "treefmt-nix"
|
"treefmt-nix": "treefmt-nix"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -110,21 +109,6 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"systems_2": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1681028828,
|
|
||||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"treefmt-nix": {
|
"treefmt-nix": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
description = "srid/haskell-template: Nix template for Haskell projects";
|
description = "srid/haskell-template: Nix template for Haskell projects";
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||||
systems.url = "github:nix-systems/default";
|
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||||
haskell-flake.url = "github:srid/haskell-flake";
|
haskell-flake.url = "github:srid/haskell-flake";
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,16 @@
|
||||||
# Generated from web app, for more information, see: https://fourmolu.github.io/config/
|
# Generated from web app, for more information, see: https://fourmolu.github.io/config/
|
||||||
indentation: 4
|
indentation: 4
|
||||||
column-limit: none
|
column-limit: none
|
||||||
function-arrows: trailing
|
function-arrows: leading
|
||||||
comma-style: leading
|
comma-style: trailing
|
||||||
import-export-style: diff-friendly
|
import-export-style: diff-friendly
|
||||||
indent-wheres: false
|
indent-wheres: false
|
||||||
record-brace-space: false
|
record-brace-space: true
|
||||||
newlines-between-decls: 1
|
newlines-between-decls: 1
|
||||||
haddock-style: multi-line
|
haddock-style: multi-line
|
||||||
haddock-style-module: null
|
haddock-style-module: single-line
|
||||||
let-style: auto
|
let-style: auto
|
||||||
in-style: right-align
|
in-style: right-align
|
||||||
single-constraint-parens: always
|
single-constraint-parens: always
|
||||||
unicode: never
|
unicode: never
|
||||||
respectful: true
|
respectful: false
|
||||||
single-deriving-parens: always
|
|
||||||
|
|
|
||||||
|
|
@ -101,8 +101,8 @@ executable image-triangles
|
||||||
-- Base language which the package is written in.
|
-- Base language which the package is written in.
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
ghc-options:
|
ghc-options:
|
||||||
-- "-fprof-auto"
|
-fprof-auto
|
||||||
-threaded
|
-- -threaded
|
||||||
"-with-rtsopts= -N"
|
"-with-rtsopts=-p"
|
||||||
-- -prof
|
-- -prof
|
||||||
-- -fexternal-interpreter
|
-- -fexternal-interpreter
|
||||||
|
|
|
||||||
20
src/Main.hs
20
src/Main.hs
|
|
@ -40,7 +40,7 @@ import System.Random.SplitMix
|
||||||
import Triangles (getTriangleAverageRGB)
|
import Triangles (getTriangleAverageRGB)
|
||||||
import qualified Triangles as Tri
|
import qualified Triangles as Tri
|
||||||
|
|
||||||
toColour :: Fractional a => Co.Color (Co.SRGB Co.Linear) a -> Colour a
|
toColour :: (Fractional a) => Co.Color (Co.SRGB Co.Linear) a -> Colour a
|
||||||
toColour (Co.ColorSRGB r g b) = CL.rgb r g b
|
toColour (Co.ColorSRGB r g b) = CL.rgb r g b
|
||||||
|
|
||||||
corners :: [(Double, Double)]
|
corners :: [(Double, Double)]
|
||||||
|
|
@ -57,7 +57,7 @@ genImage image dimensionsVec minDistance gen =
|
||||||
. mconcat
|
. mconcat
|
||||||
. map drawVoroniRegion
|
. map drawVoroniRegion
|
||||||
. sortOn shapeCircumference
|
. sortOn shapeCircumference
|
||||||
. withStrategy (parListChunk 50 rdeepseq)
|
. withStrategy (parListChunk 200 rdeepseq)
|
||||||
. map (uncurry Tri.voroniDiagramCorners)
|
. map (uncurry Tri.voroniDiagramCorners)
|
||||||
$ voroni
|
$ voroni
|
||||||
where
|
where
|
||||||
|
|
@ -95,21 +95,25 @@ genImage image dimensionsVec minDistance gen =
|
||||||
padding = (/ 10) <$> V2 1 1
|
padding = (/ 10) <$> V2 1 1
|
||||||
|
|
||||||
corners' :: [P2 Double]
|
corners' :: [P2 Double]
|
||||||
corners' = map (p2 . Bi.first (/ widthHeightRatio) . unp2 . (.-^ ((/ 2) <$> padding))) . MDS.randomPoints ((mkP2 widthHeightRatio 1) .+^ padding) (minDistance * widthHeightRatio) $ gen
|
corners' =
|
||||||
|
map (p2 . Bi.first (/ widthHeightRatio) . unp2 . (.-^ ((/ 2) <$> padding)))
|
||||||
|
. MDS.randomPoints ((mkP2 widthHeightRatio 1) .+^ padding) (minDistance * widthHeightRatio)
|
||||||
|
$ gen
|
||||||
|
|
||||||
deriving instance Generic (CL.RGB a)
|
deriving instance Generic (CL.RGB a)
|
||||||
deriving instance NFData a => NFData (CL.RGB a)
|
|
||||||
|
deriving instance (NFData a) => NFData (CL.RGB a)
|
||||||
|
|
||||||
toDimensionVector :: (Ma.Size r, Fractional a) => Ma.Array r Ma.Ix2 e -> V2 a
|
toDimensionVector :: (Ma.Size r, Fractional a) => Ma.Array r Ma.Ix2 e -> V2 a
|
||||||
toDimensionVector image =
|
toDimensionVector image =
|
||||||
p2 (fromIntegral $ cols, fromIntegral $ rows) .-. p2 (0.0, 0.0)
|
p2 (fromIntegral cols, fromIntegral rows) .-. p2 (0.0, 0.0)
|
||||||
where
|
where
|
||||||
(M.Sz2 rows cols) = Ma.size image
|
(M.Sz2 rows cols) = Ma.size image
|
||||||
|
|
||||||
data CLIOptions = CLIOptions
|
data CLIOptions = CLIOptions
|
||||||
{ input :: FilePath
|
{ input :: FilePath,
|
||||||
, output :: FilePath
|
output :: FilePath,
|
||||||
, minDistance :: Double
|
minDistance :: Double
|
||||||
}
|
}
|
||||||
deriving (Generic)
|
deriving (Generic)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ randomPolarCoord gen = do
|
||||||
distance <- uniformRM (1, 2) gen
|
distance <- uniformRM (1, 2) gen
|
||||||
pure $ view (from r2PolarIso) (distance, angle @@ turn)
|
pure $ view (from r2PolarIso) (distance, angle @@ turn)
|
||||||
|
|
||||||
randomPoints :: RandomGen r => Point V2 Double -> Double -> r -> [Point V2 Double]
|
randomPoints :: (RandomGen r) => Point V2 Double -> Double -> r -> [Point V2 Double]
|
||||||
randomPoints dims minDistance gen' = runStateGen_ gen' randomPointsM
|
randomPoints dims minDistance gen' = runStateGen_ gen' randomPointsM
|
||||||
where
|
where
|
||||||
randomPointsM gen = do
|
randomPointsM gen = do
|
||||||
|
|
@ -37,7 +37,7 @@ randomPoints dims minDistance gen' = runStateGen_ gen' randomPointsM
|
||||||
bucketSize :: Double
|
bucketSize :: Double
|
||||||
bucketSize = minDistance / (sqrt 2)
|
bucketSize = minDistance / (sqrt 2)
|
||||||
|
|
||||||
addPointToGrid grid p = M.insert (floor <$> p) (p) grid
|
addPointToGrid grid p = M.insert (floor <$> p) p grid
|
||||||
|
|
||||||
randomValueFrom xs = (xs NE.!!) <$> uniformRM (0, pred . length $ xs) gen
|
randomValueFrom xs = (xs NE.!!) <$> uniformRM (0, pred . length $ xs) gen
|
||||||
|
|
||||||
|
|
@ -45,13 +45,10 @@ randomPoints dims minDistance gen' = runStateGen_ gen' randomPointsM
|
||||||
randomPointsRec (x : xs') grid = do
|
randomPointsRec (x : xs') grid = do
|
||||||
startingPoint <- randomValueFrom xs
|
startingPoint <- randomValueFrom xs
|
||||||
newPoint <- L.find isValidPoint <$> candidates startingPoint
|
newPoint <- L.find isValidPoint <$> candidates startingPoint
|
||||||
randomPointsRec (prependIfJust newPoint $ (if My.isJust newPoint then x : xs' else xsWithout startingPoint)) . gridPlus $ newPoint
|
case newPoint of
|
||||||
|
Just newPoint' -> randomPointsRec (newPoint' : x : xs') (addPointToGrid grid newPoint')
|
||||||
|
Nothing -> randomPointsRec (xsWithout startingPoint) grid
|
||||||
where
|
where
|
||||||
prependIfJust (Just a) xs = a : xs
|
|
||||||
prependIfJust Nothing xs = xs
|
|
||||||
|
|
||||||
gridPlus = maybe grid (addPointToGrid grid)
|
|
||||||
|
|
||||||
xs :: NE.NonEmpty (Point V2 Double)
|
xs :: NE.NonEmpty (Point V2 Double)
|
||||||
xs = x NE.:| xs'
|
xs = x NE.:| xs'
|
||||||
|
|
||||||
|
|
@ -68,7 +65,7 @@ randomPoints dims minDistance gen' = runStateGen_ gen' randomPointsM
|
||||||
|
|
||||||
isValidPoint :: Point V2 Double -> Bool
|
isValidPoint :: Point V2 Double -> Bool
|
||||||
isValidPoint p =
|
isValidPoint p =
|
||||||
(Ix.inRange gridBounds (floor <$> p))
|
(Ix.inRange gridBounds . fmap floor $ p)
|
||||||
&& ( all ((>= 1) . abs . norm . (p .-.))
|
&& ( all ((>= 1) . abs . norm . (p .-.))
|
||||||
. My.mapMaybe ((grid M.!?) . fmap floor . (p .-^))
|
. My.mapMaybe ((grid M.!?) . fmap floor . (p .-^))
|
||||||
$ unitVectorsAround
|
$ unitVectorsAround
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ import Diagrams.TwoD.Segment.Bernstein (listToBernstein)
|
||||||
import qualified Graphics.Color.Space as Co
|
import qualified Graphics.Color.Space as Co
|
||||||
import System.Random
|
import System.Random
|
||||||
|
|
||||||
toColour :: Fractional a => Co.Color (Co.SRGB Co.Linear) a -> Colour a
|
toColour :: (Fractional a) => Co.Color (Co.SRGB Co.Linear) a -> Colour a
|
||||||
toColour (Co.ColorSRGB r g b) = CL.rgb r g b
|
toColour (Co.ColorSRGB r g b) = CL.rgb r g b
|
||||||
|
|
||||||
-- from -0.05 to 1.05 so there aren't missing/elongated triangles at the edges
|
-- from -0.05 to 1.05 so there aren't missing/elongated triangles at the edges
|
||||||
|
|
@ -48,7 +48,7 @@ randomPoints = map (bimap toZeroToOneTuple toZeroToOneTuple) . randomRs ((0 :: W
|
||||||
toZeroToOneTuple x = ((fromIntegral x / (fromIntegral (maxBound :: Word))) * (1 + (2 * borderSize))) - borderSize
|
toZeroToOneTuple x = ((fromIntegral x / (fromIntegral (maxBound :: Word))) * (1 + (2 * borderSize))) - borderSize
|
||||||
|
|
||||||
combinations :: (Ord b, Floating b, NFData b) => [P2 b] -> [(P2 b, P2 b)]
|
combinations :: (Ord b, Floating b, NFData b) => [P2 b] -> [(P2 b, P2 b)]
|
||||||
combinations xs =
|
combinations =
|
||||||
sortOn (abs . uncurry distanceA)
|
sortOn (abs . uncurry distanceA)
|
||||||
. S.toList -- deduplicate
|
. S.toList -- deduplicate
|
||||||
. S.fromList
|
. S.fromList
|
||||||
|
|
@ -58,19 +58,13 @@ combinations xs =
|
||||||
. map (\(x : xs) -> take 10 . sortOn (abs . uncurry distanceA) . map (x,) $ xs)
|
. map (\(x : xs) -> take 10 . sortOn (abs . uncurry distanceA) . map (x,) $ xs)
|
||||||
. init -- last output of tails is empty list
|
. init -- last output of tails is empty list
|
||||||
. tails
|
. tails
|
||||||
$ xs
|
|
||||||
where
|
|
||||||
xsLen = length xs
|
|
||||||
|
|
||||||
toPlanarGraph :: forall n. (NFData n, Floating n, Ord n) => [P2 n] -> [(Point V2 n, Point V2 n)]
|
toPlanarGraph :: forall n. (NFData n, Floating n, Ord n) => [P2 n] -> [(Point V2 n, Point V2 n)]
|
||||||
toPlanarGraph points =
|
toPlanarGraph =
|
||||||
removeIntersections
|
removeIntersections
|
||||||
. sortOn (abs . uncurry distanceA)
|
. sortOn (abs . uncurry distanceA)
|
||||||
. combinations
|
. combinations
|
||||||
$ points
|
|
||||||
where
|
where
|
||||||
numPoints = length points
|
|
||||||
|
|
||||||
removeIntersections :: [(Point V2 n, Point V2 n)] -> [(Point V2 n, Point V2 n)]
|
removeIntersections :: [(Point V2 n, Point V2 n)] -> [(Point V2 n, Point V2 n)]
|
||||||
removeIntersections = foldl' addIfNoIntersection []
|
removeIntersections = foldl' addIfNoIntersection []
|
||||||
|
|
||||||
|
|
@ -82,17 +76,17 @@ toPlanarGraph points =
|
||||||
where
|
where
|
||||||
sharedEndPoint = (< 4) . length . nub $ [fst l1, snd l1, fst l2, snd l2]
|
sharedEndPoint = (< 4) . length . nub $ [fst l1, snd l1, fst l2, snd l2]
|
||||||
|
|
||||||
toLocatedTrail :: TrailLike a => Point (V a) (N a) -> Point (V a) (N a) -> Located a
|
toLocatedTrail :: (TrailLike a) => Point (V a) (N a) -> Point (V a) (N a) -> Located a
|
||||||
toLocatedTrail p1 p2 = fromVertices [p1, p2] `at` p1
|
toLocatedTrail p1 p2 = fromVertices [p1, p2] `at` p1
|
||||||
|
|
||||||
withinShape :: RealFloat v => Point V2 v -> [Point V2 v] -> Point V2 v -> Bool
|
withinShape :: (RealFloat v) => Point V2 v -> [Point V2 v] -> Point V2 v -> Bool
|
||||||
withinShape pointInShape verticies candidate = all ((< quarterTurn) . fmap abs . uncurry signedAngleBetweenDirs) $ zip (shapeDirections pointInShape) (shapeDirections candidate)
|
withinShape pointInShape verticies candidate = all ((< quarterTurn) . fmap abs . uncurry signedAngleBetweenDirs) $ zip (shapeDirections pointInShape) (shapeDirections candidate)
|
||||||
where
|
where
|
||||||
shapeDirections p = map (dirBetween p) verticies
|
shapeDirections p = map (dirBetween p) verticies
|
||||||
|
|
||||||
sortOnAngle center = sortOn (normalizeAngle . signedAngleBetweenDirs xDir . dirBetween center)
|
sortOnAngle center = sortOn (normalizeAngle . signedAngleBetweenDirs xDir . dirBetween center)
|
||||||
|
|
||||||
voroniDiagramCorners :: RealFloat n => Point V2 n -> [Point V2 n] -> [Point V2 n]
|
voroniDiagramCorners :: (RealFloat n) => Point V2 n -> [Point V2 n] -> [Point V2 n]
|
||||||
voroniDiagramCorners center midpoints =
|
voroniDiagramCorners center midpoints =
|
||||||
sortOnAngle center
|
sortOnAngle center
|
||||||
. filter isValidMidpoint
|
. filter isValidMidpoint
|
||||||
|
|
@ -119,8 +113,8 @@ voroniDiagramCorners center midpoints =
|
||||||
. rotateBy (1 / 4)
|
. rotateBy (1 / 4)
|
||||||
$ dirBetween midpoint center
|
$ dirBetween midpoint center
|
||||||
|
|
||||||
findVoroniDiagram :: RealFloat n => [(Point V2 n, Point V2 n)] -> [(Point V2 n, [Point V2 n])]
|
findVoroniDiagram :: (RealFloat n) => [(Point V2 n, Point V2 n)] -> [(Point V2 n, [Point V2 n])]
|
||||||
findVoroniDiagram edges =
|
findVoroniDiagram =
|
||||||
M.toList
|
M.toList
|
||||||
. M.mapWithKey
|
. M.mapWithKey
|
||||||
( \key ->
|
( \key ->
|
||||||
|
|
@ -128,13 +122,11 @@ findVoroniDiagram edges =
|
||||||
. map (pointBetween key)
|
. map (pointBetween key)
|
||||||
. S.toList
|
. S.toList
|
||||||
)
|
)
|
||||||
$ adjacencyMap
|
. adjacencyMapOf
|
||||||
where
|
where
|
||||||
adjacencyMap = adjacencyMapOf edges
|
|
||||||
|
|
||||||
pointBetween p0 p1 = p0 .+^ ((p1 .-. p0) ^/ 2)
|
pointBetween p0 p1 = p0 .+^ ((p1 .-. p0) ^/ 2)
|
||||||
|
|
||||||
findTriangles :: Ord b => [(b, b)] -> S.Set (S.Set b)
|
findTriangles :: (Ord b) => [(b, b)] -> S.Set (S.Set b)
|
||||||
findTriangles edges = S.unions . S.map threeCyclesOf . M.keysSet $ adjacencyMap
|
findTriangles edges = S.unions . S.map threeCyclesOf . M.keysSet $ adjacencyMap
|
||||||
where
|
where
|
||||||
threeCyclesOf node =
|
threeCyclesOf node =
|
||||||
|
|
@ -150,26 +142,26 @@ adjacencyMapOf edges = M.fromListWith S.union . map (second S.singleton) $ (edge
|
||||||
where
|
where
|
||||||
edgesReversed = map (\(a, b) -> (b, a)) edges
|
edgesReversed = map (\(a, b) -> (b, a)) edges
|
||||||
|
|
||||||
triangleAdjacencyMap :: Ord b => S.Set (S.Set b) -> M.Map b (S.Set (S.Set b))
|
triangleAdjacencyMap :: (Ord b) => S.Set (S.Set b) -> M.Map b (S.Set (S.Set b))
|
||||||
triangleAdjacencyMap s = M.fromListWith S.union . concatMap (\s' -> map (,S.singleton s') . S.toList $ s') $ S.toList s
|
triangleAdjacencyMap s = M.fromListWith S.union . concatMap (\s' -> map (,S.singleton s') . S.toList $ s') $ S.toList s
|
||||||
|
|
||||||
getPointsInTriangle :: p -> S.Set (P2 Int) -> [(Int, Int)]
|
getPointsInTriangle :: p -> S.Set (P2 Int) -> [(Int, Int)]
|
||||||
getPointsInTriangle image pts =
|
getPointsInTriangle image pts =
|
||||||
S.toList . S.unions . map S.fromList $
|
S.toList . S.unions . map S.fromList $
|
||||||
[ ptsBtween (makeLine p1 p3) (makeLine p1 p2)
|
[ ptsBtween (makeLine p1 p3) (makeLine p1 p2),
|
||||||
, ptsBtween (makeLine p1 p3) (makeLine p2 p3)
|
ptsBtween (makeLine p1 p3) (makeLine p2 p3),
|
||||||
, ptsBtween (makeLine p1 p2) (makeLine p2 p3)
|
ptsBtween (makeLine p1 p2) (makeLine p2 p3)
|
||||||
]
|
]
|
||||||
where
|
where
|
||||||
[p1, p2, p3] = sortOn fst . map unp2 . S.toList $ pts
|
[p1, p2, p3] = sortOn fst . map unp2 . S.toList $ pts
|
||||||
|
|
||||||
blendEqually :: (Ord a, Floating a) => [Colour a] -> Colour a
|
blendEqually :: (Ord a, Floating a) => [Colour a] -> Colour a
|
||||||
blendEqually colors = C.affineCombo (zip (repeat fraction) colors) $ C.white
|
blendEqually colors = C.affineCombo (map (fraction,) colors) C.white
|
||||||
where
|
where
|
||||||
fraction = 1.0 / (fromIntegral . length $ colors)
|
fraction = 1.0 / (fromIntegral . length $ colors)
|
||||||
|
|
||||||
voroniRegionAverageColor :: (Integral a, Integral b) => Ma.Image Ma.S (Co.SRGB 'Co.Linear) Double -> (a, b) -> [P2 Double] -> Colour Double
|
voroniRegionAverageColor :: (Integral a, Integral b) => Ma.Image Ma.S (Co.SRGB 'Co.Linear) Double -> (a, b) -> [P2 Double] -> Colour Double
|
||||||
voroniRegionAverageColor image (x', y') verticies =
|
voroniRegionAverageColor image (x', y') =
|
||||||
blendEqually
|
blendEqually
|
||||||
. concatMap (getColorsInTriangle image (x', y'))
|
. concatMap (getColorsInTriangle image (x', y'))
|
||||||
. filter ((== 3) . S.size)
|
. filter ((== 3) . S.size)
|
||||||
|
|
@ -177,19 +169,16 @@ voroniRegionAverageColor image (x', y') verticies =
|
||||||
. tails
|
. tails
|
||||||
. L.nub
|
. L.nub
|
||||||
. map scaleToImageCoords
|
. map scaleToImageCoords
|
||||||
$ verticies
|
|
||||||
where
|
where
|
||||||
scaleToImageCoords :: P2 Double -> P2 Int
|
scaleToImageCoords :: P2 Double -> P2 Int
|
||||||
scaleToImageCoords p = fmap round $ p2 ((fromIntegral x' * p ^. _x), fromIntegral y' * p ^. _y)
|
scaleToImageCoords p = round <$> p2 (fromIntegral x' * p ^. _x, fromIntegral y' * p ^. _y)
|
||||||
|
|
||||||
scaleToUnitCoords :: P2 Int -> P2 Double
|
scaleToUnitCoords :: P2 Int -> P2 Double
|
||||||
scaleToUnitCoords p = p2 ((fromIntegral x' / (fromIntegral $ p ^. _x)), fromIntegral y' / (fromIntegral $ p ^. _y))
|
scaleToUnitCoords p = p2 ((fromIntegral x' / (fromIntegral $ p ^. _x)), fromIntegral y' / (fromIntegral $ p ^. _y))
|
||||||
|
|
||||||
getColorsInTriangle :: Ma.Image Ma.S (Co.SRGB 'Co.Linear) Double -> (a, b) -> S.Set (P2 Int) -> [Colour Double]
|
getColorsInTriangle :: Ma.Image Ma.S (Co.SRGB 'Co.Linear) Double -> (a, b) -> S.Set (P2 Int) -> [Colour Double]
|
||||||
getColorsInTriangle image (x', y') triangle = pixels
|
getColorsInTriangle image (x', y') triangle = mapMaybe index' points
|
||||||
where
|
where
|
||||||
pixels = mapMaybe index' points
|
|
||||||
|
|
||||||
points :: [(Int, Int)]
|
points :: [(Int, Int)]
|
||||||
points = getPointsInTriangle image triangle
|
points = getPointsInTriangle image triangle
|
||||||
|
|
||||||
|
|
@ -215,15 +204,15 @@ range' :: Int -> Int -> [Int]
|
||||||
range' a b = [(min a b) .. (max a b)]
|
range' a b = [(min a b) .. (max a b)]
|
||||||
|
|
||||||
yAt :: LineMXB -> Int -> Int
|
yAt :: LineMXB -> Int -> Int
|
||||||
yAt (LineMXB{m = m, b = b}) x = round $ (m * (fromIntegral x)) + b
|
yAt (LineMXB {..}) x = round $ (m * (fromIntegral x)) + b
|
||||||
|
|
||||||
makeLine :: (Int, Int) -> (Int, Int) -> LineMXB
|
makeLine :: (Int, Int) -> (Int, Int) -> LineMXB
|
||||||
makeLine (x1, y1) (x2, y2) =
|
makeLine (x1, y1) (x2, y2) =
|
||||||
LineMXB
|
LineMXB
|
||||||
{ m = slope
|
{ m = slope,
|
||||||
, b = (fromIntegral y1) - (slope * (fromIntegral x1))
|
b = (fromIntegral y1) - (slope * (fromIntegral x1)),
|
||||||
, startX = min x1 x2
|
startX = min x1 x2,
|
||||||
, endX = max x1 x2
|
endX = max x1 x2
|
||||||
}
|
}
|
||||||
where
|
where
|
||||||
slope =
|
slope =
|
||||||
|
|
@ -232,9 +221,9 @@ makeLine (x1, y1) (x2, y2) =
|
||||||
else fromIntegral . ceiling $ ((10.0 :: Double) ** 100.0)
|
else fromIntegral . ceiling $ ((10.0 :: Double) ** 100.0)
|
||||||
|
|
||||||
data LineMXB = LineMXB
|
data LineMXB = LineMXB
|
||||||
{ m :: Rational
|
{ m :: Rational,
|
||||||
, b :: Rational
|
b :: Rational,
|
||||||
, startX :: Int
|
startX :: Int,
|
||||||
, endX :: Int
|
endX :: Int
|
||||||
}
|
}
|
||||||
deriving (Show, Ord, Eq)
|
deriving (Show, Ord, Eq)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue