swap to nix and working version with multiple faded triangles

This commit is contained in:
Jack Wines 2018-12-17 14:25:59 -05:00
parent bc7011f86a
commit 345fcdfac1
9 changed files with 271 additions and 4 deletions

View file

@ -1 +1,31 @@
# image-triangles
make sure you have nix installed
```
curl https://nixos.org/nix/install | sh
```
to build:
```
nix-build
```
run with
```
./result/bin/image-triangles -o output.svg
```
to develop on:
```
cabal --enable-nix build
```
or
```
echo "nix: True" >> ~/.cabal/config
cabal build
```
run with
```
./dist/build/image-triangles/image-triangles -o output.svg
```

18
SVGFonts.nix Normal file
View file

@ -0,0 +1,18 @@
{ mkDerivation, attoparsec, base, blaze-markup, blaze-svg
, bytestring, cereal, cereal-vector, containers, data-default-class
, diagrams-core, diagrams-lib, directory, parsec, split, stdenv
, text, tuple, vector, xml
}:
mkDerivation {
pname = "SVGFonts";
version = "1.6.0.3";
sha256 = "bc8f8863799070c345fdd88c065852c6434af9e802fd0171df2a3dbd37f35887";
enableSeparateDataOutput = true;
libraryHaskellDepends = [
attoparsec base blaze-markup blaze-svg bytestring cereal
cereal-vector containers data-default-class diagrams-core
diagrams-lib directory parsec split text tuple vector xml
];
description = "Fonts from the SVG-Font format";
license = stdenv.lib.licenses.bsd3;
}

66
image-triangles.cabal Normal file
View file

@ -0,0 +1,66 @@
-- Initial image-triangles.cabal generated by cabal init. For further
-- documentation, see http://haskell.org/cabal/users-guide/
-- The name of the package.
name: image-triangles
-- The package version. See the Haskell package versioning policy (PVP)
-- for standards guiding when and how versions should be incremented.
-- https://wiki.haskell.org/Package_versioning_policy
-- PVP summary: +-+------- breaking API changes
-- | | +----- non-breaking API additions
-- | | | +--- code changes with no API change
version: 0.1.0.0
-- A short (one-line) description of the package.
-- synopsis:
-- A longer description of the package.
-- description:
-- The license under which the package is released.
license: BSD3
-- The file containing the license text.
license-file: LICENSE
-- The package author(s).
author: Jack Wines
-- An email address to which users can send suggestions, bug reports, and
-- patches.
maintainer: jackwines@mac.com
-- A copyright notice.
-- copyright:
-- category:
build-type: Simple
-- Extra files to be distributed with the package, such as examples or a
-- README.
extra-source-files: CHANGELOG.md, README.md
-- Constraint on the version of Cabal needed to build this package.
cabal-version: >=1.10
executable image-triangles
-- .hs or .lhs file containing the Main module.
main-is: Main.hs
-- Modules included in this executable, other than Main.
-- other-modules:
-- LANGUAGE extensions used by modules in this package.
other-extensions: TupleSections
-- Other library packages from which modules are imported.
build-depends: base, random, hip, colour, diagrams-lib, diagrams-svg
-- Directories containing source files.
hs-source-dirs: src
-- Base language which the package is written in.
default-language: Haskell2010

14
project.nix Normal file
View file

@ -0,0 +1,14 @@
{ mkDerivation, base, colour, diagrams-lib, diagrams-svg, hip
, random, stdenv
}:
mkDerivation {
pname = "image-triangles";
version = "0.1.0.0";
src = ./.;
isLibrary = false;
isExecutable = true;
executableHaskellDepends = [
base colour diagrams-lib diagrams-svg hip random
];
license = stdenv.lib.licenses.bsd3;
}

21
release.nix Normal file
View file

@ -0,0 +1,21 @@
let
config = {
packageOverrides = pkgs: rec {
haskellPackages = pkgs.haskellPackages.override {
overrides = haskellPackagesNew: haskellPackagesOld: rec {
project =
haskellPackagesNew.callPackage ./project.nix { };
SVGFonts =
haskellPackagesNew.callPackage ./SVGFonts.nix { };
};
};
};
};
pkgs = import <nixpkgs> {inherit config;};
in
{ project = pkgs.haskellPackages.project;
}

1
shell.nix Normal file
View file

@ -0,0 +1 @@
(import ./release.nix).project.env

31
src/Main.hs Normal file
View file

@ -0,0 +1,31 @@
module Main where
import qualified Triangles as Tri
import qualified Render as Ren
import Graphics.Image hiding (map)
import System.Random
import qualified Graphics.Image.ColorSpace as G
import qualified Data.Colour.SRGB as C
import Diagrams.Backend.SVG.CmdLine
import Diagrams.Prelude
genList = map mkStdGen . randoms
singleTriangle image gen = reflectY . Ren.makeTriangle (Ren.toPointList dims t) $ col
where
t = Tri.getRandomTriangle gen image
col = Tri.getTriangleAverageRGB image $ t
dims = (cols image, rows image)
main :: IO ()
main = do
image <- readImageRGB VU "sierra.jpg"
gen <- getStdGen
print gen
let t = Tri.getRandomTriangle gen image
let col = Tri.getTriangleAverageRGB image t
print col
let dims = (cols image, rows image)
mainWith . mconcat . take 50 . map (singleTriangle image) . genList $ gen

View file

@ -3,14 +3,23 @@ module Render where
import Diagrams.TrailLike
import qualified Triangles as Tri
import Diagrams.Prelude
import Diagrams.Backend.SVG.CmdLine
makeTriangle :: [Point V2 Double] -> Colour Double -> Diagram SVG
makeTriangle verts col = fromVertices verts # fc col
makeTriangle verts col = fromVertices verts # mapLoc closeLine # strokeLocLoop #fc col # lw 0 # opacity 0.2
renderTriangle = makeTriangle (map p2 [(0.0,0.0), (0.1,0.1), (0.2,0.2)]) blue
-- tupleFromIntegral :: (Int, Int) -> (Int, Int) -> (Double, Double)
tupleFromIntegral (cols, rows) (a, b) = (fromIntegral a, fromIntegral b)
-- tupleFromIntegral (cols, rows) (a, b) = ((a `divv` cols) , ((rows - b) `divv` rows))
divv :: Int -> Int -> Double
a `divv` b = (fromIntegral a) / (fromIntegral b)
toPointList :: (Int, Int) -> Tri.Triangle -> [Point V2 Double]
toPointList dims (a, b, c) = map (p2 . tupleFromIntegral dims) [a, b, c]
-- renderTriangle = makeTriangle (map p2 [(0.0,0.0), (0.1,0.1), (0.2,0.2)]) blue

77
src/Triangles.hs Normal file
View file

@ -0,0 +1,77 @@
{-# LANGUAGE TupleSections #-}
-- module Triangles
-- ( getRandomPixel
-- , getRandomTriangle
-- , getPointsInTriangle
-- , getTriangleAverageRGB
-- ) where
module Triangles where
import Graphics.Image hiding (map)
import System.Random
import qualified Data.Colour.SRGB as C
import qualified Data.Colour as C
import qualified Graphics.Image.ColorSpace as G
type Image_ = Image VU RGB Double
type Pixel_ = Pixel RGB Double
type Point = (Int, Int)
type Triangle = (Point, Point, Point)
getRandomPixel :: StdGen -> Image_ -> (Int, Int)
getRandomPixel gen image =
( getCoord gen . rows $ image
, getCoord gen' . cols $ image)
where
getCoord :: StdGen -> Int -> Int
getCoord gen = fst . (flip randomR) gen . (1,)
gen' = snd . next $ gen
first3 (a : b : c : _) = (a, b, c)
getRandomTriangle :: StdGen -> Image_ -> Triangle
getRandomTriangle gen image =
first3
. map (\x -> getRandomPixel x image)
. iterate (snd . next) $ gen
getPointsInTriangle :: Image_ -> Triangle -> [Point]
getPointsInTriangle image triangle
= filter (isPointInTriangle triangle)
$ (,) <$> [0..(rows image)] <*> [0..(cols image)]
tosRGB' (G.PixelRGB r g b) = C.sRGB r g b
blendEqually colors = C.affineCombo (zip (repeat fraction) colors) $ head colors
where
fraction = 1.0 / (fromIntegral . length $ colors)
getTriangleAverageRGB :: Image_ -> Triangle -> C.Colour Double
getTriangleAverageRGB image triangle = blendEqually . map tosRGB' $ pixels
where
nPixels :: Pixel RGB Double
nPixels = fromIntegral $ length pixels
pixels :: [Pixel_]
pixels = map (index image) points
points :: [Point]
points = getPointsInTriangle image triangle
isPointInTriangle :: Triangle -> Point -> Bool
isPointInTriangle (v1, v2, v3) pt = not (has_neg && has_pos)
where
d1 = sign pt v1 v2
d2 = sign pt v2 v3
d3 = sign pt v3 v1
has_neg = (d1 < 0) || (d2 < 0) || (d3 < 0)
has_pos = (d1 > 0) || (d2 > 0) || (d3 > 0)
sign :: Point -> Point -> Point -> Int
sign p1 p2 p3 = (fst p1 - fst p3) * (snd p2 - snd p3) - (fst p2 - fst p3) * (snd p1 - snd p3)