{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [], "source": [ "{-# LANGUAGE TypeOperators #-}\n", "import Prelude ()\n", "import qualified Prelude\n", "import Data.Manifold.TreeCover\n", "import Data.Manifold.Web\n", "import Data.Random\n", "import Data.Random.Manifold\n", "import Data.Manifold.Types\n", "import Math.LinearMap.Category\n", "import Linear(V2(..))\n", "import Data.VectorSpace\n", "import Data.Semigroup\n", "import qualified Data.List.NonEmpty as NE\n", "import Data.Foldable (toList)\n", "import Control.Monad (replicateM)\n", "\n", "import Control.Category.Constrained.Prelude\n", "import Control.Arrow.Constrained\n", ":opt no-lint -- lint gives bogus warnings with constrained-categories" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "From [dynamic-plot](http://hackage.haskell.org/package/dynamic-plot):" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import Graphics.Dynamic.Plot.R2 -- hiding (plotWindow)\n", "-- plotWindow _ = return ()\n", "import Diagrams.Prelude ((^&), (&), r2, white, opacity, fc)\n", "\n", "plotPoints :: [ℝ²] -> DynamicPlottable\n", "plotPoints ps = plot [p|±|[0.01^&0, 0^&0.01] | p<-ps]\n", "\n", "viewShadeCombination :: [Shade' ℝ²] -> [DynamicPlottable]\n", "viewShadeCombination [] = []\n", "viewShadeCombination shs' = [ plot . sconcat $ ellipsoid<$>shs\n", " , plot (mixShade's shs) & tweakPrerendered (opacity 0.3 . fc white) ]\n", " where shs = NE.fromList shs'" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "GraphWindowSpecR2{lBound=-1.5, rBound=2.4999999999999996, bBound=-0.1666666666666666, tBound=1.1666666666666665, xResolution=640, yResolution=480}" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "GraphWindowSpecR2{lBound=-1.5000000000000002, rBound=2.5, bBound=-0.16666666666666663, tBound=1.1666666666666665, xResolution=640, yResolution=480}" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plotWindow $ [plot $ viewShadeCombination [V2 0 y|±|[V2 0.5 0, V2 0 0.1], V2 y y|±|[V2 0.5 0,V2 0 0.1]]\n", " | y <- [0.1,0.3 .. 1.5] ]\n", " ++ (plot<$>[xInterval (-1,2), yInterval (0,1)])\n", "plotWindow $ [plot $ viewShadeCombination [V2 0 y|±|[V2 0.6 0,V2 0 0.1], V2 y y|±|[V2 0.33 0,V2 0 0.1]]\n", " | y <- [0.1,0.3 .. 1.5] ]\n", " ++ (plot<$>[xInterval (-1,2), yInterval (0,1)])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Convex intersection of equal, cospectral ellipses](https://raw.githubusercontent.com/leftaroundabout/manifolds/master/manifolds/images/examples/ShadeCombinations/EqualCospecEllipseIntersections.png)\n", "![Convex intersection of nonsimilar ellipses](https://raw.githubusercontent.com/leftaroundabout/manifolds/master/manifolds/images/examples/ShadeCombinations/EllipseIntersections.png)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "GraphWindowSpecR2{lBound=-1.5000000000000004, rBound=2.5000000000000004, bBound=-0.16666666666666669, tBound=1.166666666666667, xResolution=640, yResolution=480}" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plotWindow $ [plot $ viewShadeCombination [V2 0 y|±|[V2 0.5 0,V2 0 0.1], V2 0.5 (1.2*y)|±|[V2 0.5 0,V2 0 0.1]]\n", " | y <- [0.1,0.3 .. 1.5] ]\n", " ++ (plot<$>[xInterval (-1,2), yInterval (0,1)])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Convex intersection of equal, sideways offset ellipses](https://raw.githubusercontent.com/leftaroundabout/manifolds/master/manifolds/images/examples/ShadeCombinations/EqualCospecOffsetEllipseIntersections.png)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "GraphWindowSpecR2{lBound=-0.9166666666666667, rBound=2.416666666666666, bBound=-0.33333333333333326, tBound=2.333333333333333, xResolution=640, yResolution=480}" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plotWindow $ [plot $ viewShadeCombination [V2 0 0|±|[V2 0.5 (-0.5)], V2 2 0|±|[V2 0.3 0.4]]]\n", " ++ (plot<$>[xInterval (-0.5,2), yInterval (0,2)])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Convex intersection of two degenerate shades (infinite extension in some direction)](https://raw.githubusercontent.com/leftaroundabout/manifolds/master/manifolds/images/examples/ShadeCombinations/DifferentDegenerateIntersections.png)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "GraphWindowSpecR2{lBound=-0.9166666666666667, rBound=2.416666666666666, bBound=-0.33333333333333326, tBound=2.3333333333333335, xResolution=640, yResolution=480}" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plotWindow $ [plot $ viewShadeCombination [V2 0 0|±|[V2 0.5 (-0.5), V2 1 1], V2 2 0|±|[V2 0.3 0.4]]]\n", " ++ (plot<$>[xInterval (-0.5,2), yInterval (0,2)])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Convex intersection of a proper shade with a degenerate one](https://raw.githubusercontent.com/leftaroundabout/manifolds/master/manifolds/images/examples/ShadeCombinations/SinglyDegenerateIntersections.png)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "GraphWindowSpecR2{lBound=-1.0, rBound=6.999999999999999, bBound=-2.1666666666666665, tBound=3.166666666666666, xResolution=640, yResolution=480}" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plotWindow $ [ plot $ viewShadeCombination [V2 1 0|±|[V2 1 0, V2 0 3], V2 0 0|±|[V2 (-0.3) 0.4]]\n", " , plot $ viewShadeCombination [V2 4 0|±|[V2 (-0.3) 0.4], V2 5 0|±|[V2 1 0, V2 0 3]] ]\n", " ++ (plot<$>[xInterval (0,6), yInterval (-1.5,2.5)])" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "GraphWindowSpecR2{lBound=-0.6666666666666664, rBound=4.666666666666668, bBound=-1.5, tBound=2.5, xResolution=640, yResolution=480}" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plotWindow $ viewShadeCombination [ V2 0 0|±|[V2 1 0,V2 0 1]\n", " , V2 0.4 0|±|[V2 0.5 0,V2 0 0.5]\n", " , V2 1 0|±|[V2 1 0,V2 0 1]\n", " , V2 0.5 1|±|[V2 1 0,V2 0 1] ]\n", " ++ viewShadeCombination [ V2 3 0|±|[V2 1 0,V2 0 1]\n", " , V2 3.4 0|±|[V2 1.3 0,V2 0 0.4]\n", " , V2 4 0|±|[V2 1 0,V2 0 1]\n", " , V2 3.5 1|±|[V2 1 0,V2 0 1] ]\n", " ++ (plot<$>[xInterval (0,4), yInterval (-1,2)])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Convex intersection of ellipsoid sets](https://raw.githubusercontent.com/leftaroundabout/manifolds/master/manifolds/images/examples/ShadeCombinations/ConvexIntersections.png)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Shade' {_shade'Ctr = 0.0, _shade'Narrowness = spanNorm [0.5000000000000002]}" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "convolveShade' (0|±|[1]) (0|±|[1]) :: Shade' ℝ" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Shade' {_shade'Ctr = (0.0,0.0), _shade'Narrowness = spanNorm [(9.999999999983312e-3,0.0),(0.0,9.999999999983312e-3)]}" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "convolveShade' ((0,0)|±|[(1,0),(0,1)]) ((0,0)|±|[(99,0),(0,99)]) :: Shade' (ℝ,ℝ)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [], "source": [ "convoTests :: [[Shade' (ℝ,ℝ)]]\n", "convoTests = [ [ (0,6) |±| [(4,0),(0,2)]\n", " , (9,4) |±| [(4,0),(0,2)] ]\n", " , [ (8,0) |±| [(4,0),(0,1)]\n", " , (0,8) |±| [(1,0),(0,4)] ]\n", " , [ (9,0) |±| [(2 ,2) ,(0.1,2.5)]\n", " , (0,8) |±| [(0.5,-0.1),(1,3)] ]\n", " , [ (8,0) |±| [(1 ,-0.7)]\n", " , (0,8) |±| [(0.7,-0.2),(2.7 ,2 )] ]\n", " , [ (2,6) |±| [(4,0),(0,4)]\n", " , (9,0) |±| [(1,0),(0,0.1)] ] ]" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "forM_ convoTests $ \\wings -> do\n", " let convo = convolveShade' (wings!!0) (wings!!1)\n", " \n", " testPts <- runRVar (forM wings $ \\sh@(Shade' cs es) ->\n", " fmap (filter $ \\p -> occlusion sh p > exp(-1))\n", " . replicateM 150 $ do\n", " φ <- uniform 0 (2*pi)\n", " r <- normal 1 0.1\n", " let [v₁,v₂] = normSpanningSystem' es\n", " return $ cs ^+^ (r*cos φ)*^v₁ ^+^ (r*sin φ)*^v₂\n", " ) StdRandom :: IO [[(ℝ,ℝ)]]\n", "\n", " plotWindow $ [ plot [plot sh, plotPoints $ r2 <$> tps]\n", " | (sh,tps) <- zip (convo:wings) ([a^+^b | a<-testPts!!0, b<-testPts!!1] : testPts)]\n", " ++ (plot<$>[xInterval (0,16), yInterval (1,12)])" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "\n", "![Convolution of coaligned shades](https://raw.githubusercontent.com/leftaroundabout/manifolds/master/manifolds/images/examples/ShadeCombinations/2Dconvolution-coaligned.png)\n", "![Convolution of \"orthogonal\" shades](https://raw.githubusercontent.com/leftaroundabout/manifolds/master/manifolds/images/examples/ShadeCombinations/2Dconvolution-orthogonal.png)\n", "![Convolution of skewed shades](https://raw.githubusercontent.com/leftaroundabout/manifolds/master/manifolds/images/examples/ShadeCombinations/2Dconvolution-skewed.png)\n", "![Convolution of a compact shade and a degenerate one](https://raw.githubusercontent.com/leftaroundabout/manifolds/master/manifolds/images/examples/ShadeCombinations/2Dconvolution-degenerate.png)\n", "![Convolution of shades with very different shape](https://raw.githubusercontent.com/leftaroundabout/manifolds/master/manifolds/images/examples/ShadeCombinations/2Dconvolution-big+small.png)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "GraphWindowSpecR2{lBound=-2.456011329583298, rBound=13.192079307083088, bBound=-0.9969665083072043, tBound=4.983644332615075, xResolution=640, yResolution=480}" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import Data.Manifold.Riemannian\n", "\n", "interpolate₀, interpolate₁ :: Shade (ℝ,ℝ)\n", "interpolate₀ = (0,1):±[(0.5,0),(0,1)]\n", "interpolate₁ = (9,2):±[(2,1),(1,2)]\n", "\n", "Just interpolation = geodesicBetween interpolate₀ interpolate₁\n", "\n", "plotWindow [ plot interpolate₀\n", " , plot [ plot $ interpolation (D¹ x)\n", " | x <- [-0.6, -0.2 .. 0.6] ]\n", " , plot interpolate₁]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Interpolating between shades, with location and extend](https://raw.githubusercontent.com/leftaroundabout/manifolds/master/manifolds/images/examples/ShadeCombinations/interpolation_straight2skewed.png)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "GraphWindowSpecR2{lBound=-2.4560113295832986, rBound=13.192079307083088, bBound=-0.9814239699997196, tBound=4.981423969999719, xResolution=640, yResolution=480}" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "interpolate₀, interpolate₁ :: Shade (ℝ,ℝ)\n", "interpolate₀ = (0,1):±[(0.5,-0.5)]\n", "interpolate₁ = (9,2):±[(2,1),(1,2)]\n", "\n", "Just interpolation = geodesicBetween interpolate₀ interpolate₁\n", "\n", "plotWindow [ plot interpolate₀\n", " , plot [ plot $ interpolation (D¹ x)\n", " | x <- [-0.6, -0.2 .. 0.6] ]\n", " , plot interpolate₁]" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "GraphWindowSpecR2{lBound=-1.3333333333333328, rBound=1.3333333333333328, bBound=-1.3333333333333328, tBound=1.3333333333333328, xResolution=640, yResolution=480}" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "interpolate₀', interpolate₁' :: Shade' (ℝ,ℝ)\n", "interpolate₀' = (-1,-1)|±|[(0.1,0),(0,0.2)]\n", "interpolate₁' = (1,1) |±|[(0.1,0.2),(-0.3,0.3)]\n", "\n", "Just interpolation' = geodesicBetween interpolate₀' interpolate₁'\n", "\n", "plotWindow [ plot interpolate₀'\n", " , plot [ plot $ interpolation' (D¹ x)\n", " | x <- [-0.6, -0.2 .. 0.6] ]\n", " , plot interpolate₁']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Interpolating between co-shades, with location and extend](https://raw.githubusercontent.com/leftaroundabout/manifolds/master/manifolds/images/examples/ShadeCombinations/interpolation'_straight2skewed.png)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "GraphWindowSpecR2{lBound=-1.333333333333333, rBound=1.333333333333333, bBound=-1.333333333333333, tBound=1.333333333333333, xResolution=640, yResolution=480}" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "let pss = [[(-1)^&0, (-1)^&0.1, 0^&0, 0^&(0.1), 1^&0.2, 1^&ye :: ℝ²] | ye <- [0.3,0.31..]]\n", " in plotWindow [plotLatest [[plotPoints ps, plotLatest (pointsCover's ps :: [Shade' ℝ²])] | ps<-pss]]" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "![Convex hull of a set of points with an outlier](https://raw.githubusercontent.com/leftaroundabout/manifolds/master/manifolds/images/examples/ShadeCombinations/OutlierPoints-ConvexHull.gif)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Haskell", "language": "haskell", "name": "haskell" }, "language_info": { "codemirror_mode": "ihaskell", "file_extension": ".hs", "name": "haskell", "version": "7.10.2" } }, "nbformat": 4, "nbformat_minor": 0 }