-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d9b7e1a
commit e847f7b
Showing
3 changed files
with
63 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,16 @@ | ||
module Data.Vector | ||
( Vector(Vector) ) where | ||
( Vector(..) ) where | ||
|
||
data Vector a = Vector a a a | ||
deriving (Show, Eq) | ||
|
||
instance (Num a) => Num (Vector a) where | ||
(Vector x1 y1 z1) + (Vector x2 y2 z2) = Vector (x1+x2) (y1+y2) (z1+z2) | ||
(*) = undefined | ||
(Vector x1 y1 z1) * (Vector x2 y2 z2) = Vector (x1*x2) (y1*y2) (z1*z2) | ||
abs = undefined | ||
signum = undefined | ||
fromInteger = undefined | ||
negate = undefined | ||
|
||
instance Functor Vector where | ||
fmap f (Vector x y z) = Vector (f x) (f y) (f z) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,67 @@ | ||
module Main where | ||
|
||
import Data.Vector | ||
import System.Console.Terminal.Size | ||
|
||
_r :: Float | ||
_r = 1.0 | ||
_R :: Float | ||
_R = 2.0 | ||
type ScreenPos = (Int, Int) | ||
|
||
drawCircle :: Vector Float -> [Vector Float] | ||
drawCircle center = map ((+) center . vradius) [0,0.1..2*pi] | ||
where | ||
type Grid = [[Char]] | ||
|
||
k :: Float | ||
k = 1 | ||
|
||
-- | A torus is essentially a circle cloned around a central point; | ||
-- we thus define r as being the radius of the center, | ||
r :: Float | ||
r = 5 | ||
-- and r' a being the distance between the center of the | ||
-- circle and the central point of the torus. | ||
r' :: Float | ||
r' = 25 | ||
|
||
-- | Generates every point of a circle of radius r and | ||
-- center c. | ||
generateCircle :: Vector Float -> [Vector Float] | ||
generateCircle c = map ((+) c . vradius) [0.0,0.05..2*pi] | ||
where | ||
-- | Generates a vector corresponding to the | ||
-- radius, rotated by the given angle theta. | ||
-- It is centered at point (0,0,0); we need to add that | ||
-- vector the vector c. | ||
vradius :: Float -> Vector Float | ||
vradius theta = Vector (_r * cos theta) (_r * sin theta) 0 | ||
vradius theta = Vector (r * cos theta) (r * sin theta) 0 | ||
|
||
-- | Projects a vector to a point on the screen | ||
project :: Vector Float -> ScreenPos | ||
project v@(Vector _ _ z) = pair . fmap (round . (* (k/z))) $ v | ||
where pair (Vector x y _) = (x, y) | ||
|
||
render :: [[Char]] | ||
render = ["hello", "world"] | ||
-- | Creates our final render made out of char, | ||
-- based on screen coordinates that must get rendered. | ||
renderScreenCoordinates :: [ScreenPos] -> Grid | ||
renderScreenCoordinates coordinates = | ||
map (concatMap (\cell -> if mustRender cell then ".." else " ")) gridCoordinates | ||
where | ||
gridCoordinates :: [[ScreenPos]] | ||
gridCoordinates = [ | ||
[ (x, y) | x <- take 40 [0..] ] | ||
| y <- take 24 [0..] ] | ||
|
||
mustRender :: ScreenPos -> Bool | ||
mustRender pos = pos `elem` coordinates | ||
|
||
-- | Starts the rendering process. | ||
render :: Window Int -> [[Char]] | ||
render win@(Window w h) = coordinates | ||
where | ||
coordinates = renderScreenCoordinates $ map project $ generateCircle (Vector r' 5 1) | ||
|
||
main :: IO () | ||
main = do | ||
let screen = unlines render | ||
window <- size | ||
window <- case window of | ||
Just a -> return a | ||
Nothing -> return $ Window 80 24 | ||
|
||
let screen = unlines $ render window | ||
putStr screen |