change raster method, add todo to readme
This commit is contained in:
parent
6e61dc893d
commit
221a43e835
5 changed files with 87 additions and 11 deletions
16
README.md
16
README.md
|
|
@ -5,7 +5,7 @@ make sure you have nix installed
|
|||
curl https://nixos.org/nix/install | sh
|
||||
```
|
||||
|
||||
to build:
|
||||
### to build:
|
||||
```
|
||||
nix-build
|
||||
|
||||
|
|
@ -15,7 +15,7 @@ run with
|
|||
./result/bin/image-triangles -o output.svg
|
||||
```
|
||||
|
||||
to develop on:
|
||||
### to develop on:
|
||||
```
|
||||
cabal --enable-nix build
|
||||
```
|
||||
|
|
@ -29,3 +29,15 @@ run with
|
|||
```
|
||||
./dist/build/image-triangles/image-triangles -o output.svg
|
||||
```
|
||||
|
||||
### todo
|
||||
- Why is the area wrong for the top right corner?
|
||||
- Rasterization for triangles
|
||||
- Cmdline interface that lets you set number of triangles, and smallness
|
||||
- Pointy triangle filter
|
||||
- Confirm diagrams is rendering triangles in the correct places.
|
||||
- Cache transformations to the colors library
|
||||
- Hip has a map transformation. It also depends on the colours library, does it use it?
|
||||
- Check that hip colors are srgb
|
||||
- Think about opacity. What if everything was completely opaque? What should we do with areas that aren’t 100% covered at the end?
|
||||
|
||||
|
|
|
|||
|
|
@ -64,4 +64,4 @@ executable image-triangles
|
|||
|
||||
-- Base language which the package is written in.
|
||||
default-language: Haskell2010
|
||||
ghc-options: -threaded -O3
|
||||
ghc-options: -threaded
|
||||
|
|
|
|||
|
|
@ -26,5 +26,7 @@ main = do
|
|||
gen <- getStdGen
|
||||
print gen
|
||||
let dims = (cols image, rows image)
|
||||
let triangleList = sortOn (Tri.area) . withStrategy (parListChunk 50 rseq) . take 600 . map (Tri.getRandomTriangle image) . genList $ gen
|
||||
mainWith . mconcat . map (renderTri image) $ triangleList
|
||||
let triangleList = take 200 . sortOn (negate . Tri.area) . take 500 . map (Tri.getRandomTriangle image) . genList $ gen
|
||||
-- print $ map Tri.area $ take 20 $ triangleList
|
||||
-- print $ Tri.area . last $ triangleList
|
||||
mainWith . mconcat . withStrategy (parListChunk 50 rseq) . map (renderTri image) $ triangleList
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ makeTriangle verts col = fromVertices verts
|
|||
# strokeLocLoop
|
||||
# fc col
|
||||
# lw 0
|
||||
# opacity 0.2
|
||||
# opacity 0.8
|
||||
|
||||
|
||||
-- tupleFromIntegral :: (Int, Int) -> (Int, Int) -> (Double, Double)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
module Triangles where
|
||||
|
||||
import Graphics.Image hiding (map)
|
||||
import Graphics.Image hiding (map, zipWith, sum, minimum, maximum)
|
||||
import System.Random
|
||||
import qualified Data.Colour.SRGB as C
|
||||
import qualified Data.Colour as C
|
||||
|
|
@ -21,8 +21,18 @@ type Pixel_ = Pixel RGB Double
|
|||
type Point = (Int, Int)
|
||||
type Triangle = (Point, Point, Point)
|
||||
|
||||
shoelace :: [Point] -> Double
|
||||
shoelace pts = halve . sum $ zipWith (*) (zipWith (+) xs' xs) (zipWith (-) ys' ys)
|
||||
where
|
||||
xs = map snd pts
|
||||
ys = map fst pts
|
||||
ys' = tail . cycle $ xs
|
||||
xs' = tail . cycle $ ys
|
||||
halve b = (fromIntegral b) / 2.0
|
||||
|
||||
area :: Triangle -> Double
|
||||
area (p1, p2, p3) = ccArea . swapForCounterClockwise . sortOn fst $ [p1, p2, p3]
|
||||
area (p1, p2, p3) = abs . shoelace $ [p1, p2, p3]
|
||||
-- area (p1, p2, p3) = abs . ccArea . swapForCounterClockwise . sortOn fst $ [p1, p2, p3]
|
||||
where
|
||||
swapForCounterClockwise [a, b, c] = if snd a < snd b
|
||||
then [a, b, c]
|
||||
|
|
@ -50,9 +60,19 @@ getRandomTriangle image gen =
|
|||
. iterate (snd . next) $ gen
|
||||
|
||||
getPointsInTriangle :: Image_ -> Triangle -> [Point]
|
||||
getPointsInTriangle image triangle
|
||||
= filter (isPointInTriangle triangle)
|
||||
$ (,) <$> [0..(rows image)] <*> [0..(cols image)]
|
||||
getPointsInTriangle image (p1', p2', p3') = (ptsBtween (p1, p3) (p1, p2)) ++
|
||||
(ptsBtween (p1, p3) (p2, p3))
|
||||
where
|
||||
sortedPoints = sortOn snd [p1', p2', p3']
|
||||
|
||||
p1 = sortedPoints !! 0
|
||||
p2 = sortedPoints !! 1
|
||||
p3 = sortedPoints !! 2
|
||||
|
||||
-- getPointsInTriangle image triangle =
|
||||
-- = filter (isPointInTriangle triangle)
|
||||
-- $ (,) <$> [0..(rows image)] <*> [0..(cols image)]
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -74,6 +94,48 @@ getTriangleAverageRGB image triangle = blendEqually . map tosRGB' $ pixels
|
|||
points :: [Point]
|
||||
points = getPointsInTriangle image triangle
|
||||
|
||||
-- pointsInTriangle image (p1, p2, p3) =
|
||||
-- where
|
||||
-- sortedPts = sortOn snd [p1, p2, p3]
|
||||
|
||||
ptsBtween :: (Point, Point) -> (Point, Point) -> [Point]
|
||||
ptsBtween (l1p1, l1p2) (l2p1, l2p2) = concatMap rasterLine [startingX .. endingX]
|
||||
where
|
||||
l1 = makeLine l1p1 l1p2
|
||||
l2 = makeLine l2p1 l2p2
|
||||
|
||||
l1Xs = map snd [l1p1, l1p2]
|
||||
l2Xs = map snd [l2p1, l2p2]
|
||||
|
||||
startingX = max (minimum l1Xs) (minimum l2Xs)
|
||||
endingX = min (maximum l1Xs) (maximum l2Xs)
|
||||
|
||||
rasterLine x = map (\y -> (y, x)) $ range' (yAt l1 x) (yAt l2 x)
|
||||
|
||||
|
||||
|
||||
|
||||
range' :: Int -> Int -> [Int]
|
||||
range' a b = [(min a b) .. (max a b)]
|
||||
|
||||
yAt :: Line -> Int -> Int
|
||||
yAt (Line {m = m, b = b}) x = round $ (m * (fromIntegral x)) + b
|
||||
|
||||
-- y = mx + b
|
||||
-- y - mx = b
|
||||
makeLine :: Point -> Point -> Line
|
||||
makeLine (y1, x1) (y2, x2) = Line {m = slope, b = (fromIntegral y1) - (slope * (fromIntegral x1))}
|
||||
where
|
||||
slope = (y1 - y2) `doubleDiv` (x1 - x2)
|
||||
|
||||
doubleDiv a b = (fromIntegral a) / (fromIntegral b)
|
||||
|
||||
data Line = Line
|
||||
{
|
||||
m :: Double,
|
||||
b :: Double
|
||||
}
|
||||
|
||||
isPointInTriangle :: Triangle -> Point -> Bool
|
||||
isPointInTriangle (v1, v2, v3) pt = not (has_neg && has_pos)
|
||||
where
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue