From e90f93a0e20e4f1b5db4a779d5cbe5f465fe509c Mon Sep 17 00:00:00 2001 From: David Himmelstrup Date: Wed, 4 Dec 2019 16:28:04 +0800 Subject: [PATCH] Update tutorial. Former-commit-id: f26d6e4164a5baf82671b8079981bfddc247a17c --- docs/glue_tut.md | 21 +++++--- examples/tut_glue_povray.hs | 101 ++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 7 deletions(-) create mode 100755 examples/tut_glue_povray.hs diff --git a/docs/glue_tut.md b/docs/glue_tut.md index 410762a..f2dfa64 100644 --- a/docs/glue_tut.md +++ b/docs/glue_tut.md @@ -82,9 +82,7 @@ The following examples shows how something as seemingly complicated as fourier s - -TODO: Write about how lots of libraries are available for Haskell. Use chiphunk - as an example. Show SVG primitives with 2D physics. +Scripting in Haskell also gives access to the extensive body of code libraries. There are Haskell libraries for syntax highlighting, font manipulation, and much, much more. In the spirit of being a batteries-included framework, Reanimate ships with a built-in 2D physics library, called Chipmunk2D. The example below demonstrates how SVG shapes can be generated with LaTeX and then nearly effortlessly used in a physics simulation.
Toggle source code. @@ -101,10 +99,12 @@ TODO: Write about how lots of libraries are available for Haskell. Use chiphunk ## Pillar II: LaTeX -TODO: Show that LaTeX is a provider of SVG graphics. It has the type - 'latex :: Text -> SVG'. Caching is automatic and it plays well with - other SVG functions (partialSvg, center, etc). +LaTeX is a widely used system for typesetting equations and documents. It is most commonly used by writing TeX documents which are then converted to pdfs. However, since the output of LaTeX is natively vector graphics, it is trivial to get SVG documents instead of pdfs. Armed with this knowledge, Reanimate offers a simple yet powerful function: `latex :: Text -> SVG` + +The `latex` function takes a snippet of TeX code, passes it through the LaTeX system, and converts the result to an SVG image. Furthermore, since the result is entirely determined by the TeX code, caching is used to hide the overhead of invoking LaTeX. + +The resulting SVGs can be manipulated just like any other. The below examples illustrates how different effects can be applied to different glyphs in the equation.
Toggle source code. @@ -120,6 +120,13 @@ TODO: Show that LaTeX is a provider of SVG graphics. It has the type ## Pillar III: potrace -## Pillar IV: Povray +## Pillar IV: povray + +TODO: Draw text and animate shapes, zoom out so it looks like a piece of paper (still animated), draw circle, fade in rotating sphere. ## Pillar V: Blender + +TODO: Crumble SVG animation. + +TODO: Morph SVG animation into sphere. + diff --git a/examples/tut_glue_povray.hs b/examples/tut_glue_povray.hs new file mode 100755 index 0000000..1b140a6 --- /dev/null +++ b/examples/tut_glue_povray.hs @@ -0,0 +1,101 @@ +#!/usr/bin/env stack +-- stack runghc --package reanimate +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE QuasiQuotes #-} +module Main (main) where + +import Reanimate +import Reanimate.Povray +import Reanimate.Raster +import Data.String.Here +import Data.Text (Text) + +main :: IO () +main = reanimate $ mkAnimation 5 $ \t -> + let s = fromToS 1 4 t in + mkGroup + [ mkBackground "black" + , povray [] (script (svgAsPngFile texture) s) ] + where + +texture :: SVG +texture = checker 10 10 + +script :: FilePath -> Double -> Text +script png s = [iTrim| +//EXAMPLE OF SPHERE + +//Files with predefined colors and textures +#include "colors.inc" +#include "glass.inc" +#include "golds.inc" +#include "metals.inc" +#include "stones.inc" +#include "woods.inc" + +#include "shapes3.inc" + +//Place the camera +camera { + //orthographic + perspective + // angle 50 + location <0,-${max 0 (((s**1.5)-1)/16)},-3> + look_at <0,0,0> + //right x*image_width/image_height + up <0,9,0> + right <16,0,0> +} + + + +//Ambient light to "brighten up" darker pictures +global_settings { ambient_light White*3 } + +//Set a background color +//background { color White } +//background { color rgbt <0.1, 0, 0, 0> } // red +background { color rgbt <0, 0, 0, 1> } // transparent + +polygon { + 4, + //<-9, -4.5>, <-9, 4.5>, <9, 4.5>, <9, -4.5> + <0, 0>, <0, 1>, <1.777, 1>, <1.777, 0> + texture { + //pigment{ color rgb <0,0,1> } + pigment{ + image_map{ png ${png} } + } + } + translate <-1.777/2,-0.5> + scale 9 +} + + |] + +checker :: Int -> Int -> SVG +checker w h = + withFillColor "white" $ + withStrokeColor "white" $ + withStrokeWidth 0.1 $ + mkGroup + [ withStrokeWidth 0 $ + withFillOpacity 1 $ mkBackground "blue" + , mkGroup + [ translate (stepX*x-offsetX + stepX/2) 0 $ + mkLine (0, -screenHeight/2*0.9) (0, screenHeight/2*0.9) + | x <- map fromIntegral [0..w-1] + ] + , + mkGroup + [ translate 0 (stepY*y-offsetY) $ + mkLine (-screenWidth/2, 0) (screenWidth/2, 0) + | y <- map fromIntegral [0..h] + ] + ] + where + stepX = screenWidth/fromIntegral w + stepY = screenHeight/fromIntegral h + offsetX = screenWidth/2 + offsetY = screenHeight/2 +