-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathTSPGraph.hs
75 lines (59 loc) · 2.27 KB
/
TSPGraph.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
module TSPGraph (
presentUI
) where
import Graphics.Gloss
import TSPLib
import Data.Monoid
import Data.Functor
import Control.Arrow ((***))
imgWidth, imgHeight :: Int
imgWidth = 600
imgHeight = 600
main :: IO ()
main = do
(nodes, edges) <- parseInput
presentUI nodes edges
presentUI :: [Node] -> [Edge] -> IO ()
presentUI nodes edges =
let window = InWindow "TSP Visualize" (imgWidth, imgHeight) (10, 10)
(halfW, halfH) = (fromIntegral (-imgWidth)/2, fromIntegral (-imgHeight)/2)
translatedPic = scale 0.9 (-0.9) $ translate halfW halfH pic
(xrng, yrng) = (xRange nodes, yRange nodes)
pic = paintNodes nodes xrng yrng <>
paintEdges edges xrng yrng
in display window white translatedPic
scaleVal :: (Fractional a) => (a, a) -> a -> a -> a
scaleVal (xmin, xmax) scl x = scl * (x - xmin) / (xmax - xmin)
scaleVal' :: (Int, Int) -> Int -> Int -> Float
scaleVal' rng scl = scaleVal fltrng fltscl . fromIntegral
where fltrng = tupleFromIntegral rng
fltscl = fromIntegral scl
scaleTuple :: (Int, Int) -> (Int, Int) -> Int -> Int ->
(Int, Int) -> (Float, Float)
scaleTuple xrng yrng xmax ymax = scaleX *** scaleY
where scaleX = scaleVal' xrng xmax
scaleY = scaleVal' yrng ymax
paintNodes :: [Node] -> (Int,Int) -> (Int,Int) -> Picture
paintNodes [] _ _ = blank
paintNodes [_] _ _ = blank
paintNodes ns xr yr = pictures $ zipWith paintNode [(0::Int)..] ns
where scalePoint = scaleTuple xr yr imgWidth imgHeight
getcolor n = if n == 0 then red else black
paintNode n node = uncurry translate (scalePoint node) $
color (getcolor n) $
circle 5
paintEdges :: [Edge] -> (Int,Int) -> (Int,Int) -> Picture
paintEdges [] _ _ = blank
paintEdges [_] _ _ = blank
paintEdges ns xr yr = pictures $ map paintEdge ns
where scalePoint = scaleTuple xr yr imgWidth imgHeight
paintEdge (p1, p2) = color blue $ line [scalePoint p1, scalePoint p2]
parseInput :: IO ([Node], [Edge])
parseInput = do
(cfg:raw) <- lines <$> getContents
let [nn, _] = map read $ words cfg
rest = map (map read . words) raw
(ns, es) = splitAt nn rest
nodes = map (\[a,b] -> (a,b)) ns
edges = map (\[a,b,c,d] -> ((a,b), (c,d))) es
in return (nodes, edges)