<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"
    xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel>
        <title>Diagrams Blog - RSS feed</title>
        <link>http://projects.haskell.org/diagrams</link>
        <description><![CDATA[Diagrams Blog Posts]]></description>
        <atom:link href="http://projects.haskell.org/diagrams/rss.xml" rel="self"
                   type="application/rss+xml" />
        <lastBuildDate>Tue, 03 Jan 2017 00:00:00 UT</lastBuildDate>
        <item>
    <title>Diagrams 1.4</title>
    <link>http://projects.haskell.org/diagrams/blog/2017-01-03-diagrams-1.4.html</link>
    <description><![CDATA[<div class="blog-header">
    <p>by <em>Brent Yorgey</em> on <strong>January  3, 2017</strong></p>
    <p>Tagged as: <a href="http://projects.haskell.org/diagrams/tags/release.html">release</a>, <a href="http://projects.haskell.org/diagrams/tags/features.html">features</a>, <a href="http://projects.haskell.org/diagrams/tags/announcement.html">announcement</a>, <a href="http://projects.haskell.org/diagrams/tags/1.4.html">1.4</a>.</p>
</div>

<div>
    <?xml version="1.0" encoding="UTF-8" ?>
<div class="container bs-docs-container"><div class="row"><div class="col-md-3"><div class="bs-sidebar hidden-print" role="complementary" data-spy="affix"></div></div><div class="col-md-9"><h1 class="title">Diagrams 1.4</h1><p>The diagrams team is very pleased to announce the release of diagrams
1.4.  The release actually happened a few months ago, in October—we
just hadn't gotten around to writing about it yet.  But in any case
this was a fairly quiet release, with very few breaking changes;
mostly 1.4 just introduced new features.  There is a <a class="reference external" href="https://wiki.haskell.org/Diagrams/Dev/Migrate1.4">migration
guide</a> which lists a few known potentially breaking changes, but most
users should have no trouble.  The rest of this post highlights some
of the new features in 1.4.</p><div class="section" id="alignment-and-layout"><h1>Alignment and layout</h1><div class="section" id="radial-tree-layout"><h2>Radial tree layout</h2><p>The existing <span class="module"><a href="http://projects.haskell.org/diagrams/haddock/Diagrams-TwoD-Layout-Tree.html"><code>Diagrams.TwoD.Layout.Tree</code></a></span> module from
<span class="package"><a href="http://hackage.haskell.org/package/diagrams-contrib"><code>diagrams-contrib</code></a></span> has been extended with a new <code class="sourceCode">radialLayout</code>
function, based on an <a class="reference external" href="http://www.cs.cmu.edu/~pavlo/static/papers/APavloThesis032006.pdf">algorithm by Andy Pavlo</a>.</p><div class="dia-lhs panel panel-default"><div class="panel-body"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/69c4f35e79910ce9.png" width="500" height="200" /></div><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> <span class="kw">import </span><span class="dt">Diagrams.TwoD.Layout.Tree</span>
<span class="ot">></span> <span class="kw">import </span><span class="dt">Data.Tree</span>
<span class="ot">></span>
<span class="ot">></span> t <span class="fu">=</span> <span class="dt">Node</span> <span class="ch">'A'</span>
<span class="ot">></span>     [ <span class="dt">Node</span> <span class="ch">'B'</span> (map lf <span class="st">"CDE"</span>)
<span class="ot">></span>     , <span class="dt">Node</span> <span class="ch">'F'</span> [<span class="dt">Node</span> <span class="ch">'G'</span> (map lf <span class="st">"HIJKLM"</span>), <span class="dt">Node</span> <span class="ch">'N'</span> (map lf <span class="st">"OPQRS"</span>)]
<span class="ot">></span>     , <span class="dt">Node</span> <span class="ch">'T'</span> (map lf <span class="st">"UVWXYZ"</span>)
<span class="ot">></span>     ]
<span class="ot">></span>   <span class="kw">where</span> lf x <span class="fu">=</span> <span class="dt">Node</span> x []
<span class="ot">></span>
<span class="ot">></span> example <span class="fu">=</span>
<span class="ot">></span>    renderTree (\n <span class="ot">-></span> (text (show n) <span class="fu">#</span> fontSizeG <span class="fl">0.5</span>
<span class="ot">></span>                             <span class="fu"><></span> circle <span class="fl">0.5</span> <span class="fu">#</span> fc white))
<span class="ot">></span>              (<span class="fu">~~</span>) (radialLayout t)
<span class="ot">></span>    <span class="fu">#</span> centerXY <span class="fu">#</span> frame <span class="fl">0.5</span></code></pre></div></div></div></div><div class="section" id="aligned-composition"><h2>Aligned composition</h2><p>Sometimes, it is desirable to compose some diagrams according to a
certain alignment, but without affecting their local origins. The
<code class="sourceCode">composeAligned</code> function can be used for this purpose. It takes as
arguments an alignment function (such as <code class="sourceCode">alignT</code> or <code class="sourceCode">snugL</code>), a
composition function of type <code>[Diagram] -> Diagram</code>, and produces a
new composition function which works by first aligning the diagrams
before composing them.</p><div class="dia-lhs panel panel-default"><div class="panel-body"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/efb94a1abf753555.png" width="500" height="200" /></div><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">> example ::</span> <span class="dt">Diagram</span> <span class="dt">B</span>
<span class="ot">></span> example <span class="fu">=</span> (hsep <span class="dv">2</span> <span class="fu">#</span> composeAligned alignT) (map circle [<span class="dv">5</span>,<span class="dv">1</span>,<span class="dv">3</span>,<span class="dv">2</span>])
<span class="ot">></span>         <span class="fu">#</span> showOrigin</code></pre></div></div></div><p>The example above shows using <code class="sourceCode">hsep <span class="dv">2</span></code> to compose a collection of
top-aligned circles.  Notice how the origin of the composed diagram is
still at the center of the leftmost circle, instead of at its top edge
(where it would normally be placed by <code class="sourceCode">alignT</code>).</p></div><div class="section" id="constrained-layout"><h2>Constrained layout</h2><p>The new <span class="module"><a href="http://projects.haskell.org/diagrams/haddock/Diagrams-TwoD-Layout-Constrained.html"><code>Diagrams.TwoD.Layout.Constrained</code></a></span> module from
<span class="package"><a href="http://hackage.haskell.org/package/diagrams-contrib"><code>diagrams-contrib</code></a></span> implements basic linear constraint-based
layout.  As a simple example of something that would be tedious to
draw without some kind of constraint solving, consider this diagram
which consists of a vertical stack of circles of different sizes,
along with an accompanying set of squares, such that (1) each square
is constrained to lie on the same horizontal line as a circle, and (2)
the squares all lie on a diagonal line.</p><div class="dia-lhs panel panel-default"><div class="panel-body"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/9072ef90694fb4b9.png" width="500" height="200" /></div><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> <span class="kw">import </span><span class="dt">Diagrams.TwoD.Layout.Constrained</span>
<span class="ot">></span> <span class="kw">import </span><span class="dt">Control.Monad</span> (zipWithM_)
<span class="ot">></span>
<span class="ot">> example ::</span> <span class="dt">Diagram</span> <span class="dt">B</span>
<span class="ot">></span> example <span class="fu">=</span> frame <span class="dv">1</span> <span class="fu">$</span> layout <span class="fu">$</span> <span class="kw">do</span>
<span class="ot">></span>   <span class="kw">let</span> rs <span class="fu">=</span> [<span class="dv">2</span>,<span class="dv">2</span>,<span class="dv">4</span>,<span class="dv">3</span>,<span class="dv">5</span>,<span class="dv">6</span>]
<span class="ot">></span>   cirs <span class="ot"><-</span> newDias (map circle rs <span class="fu">#</span> fc blue)
<span class="ot">></span>   sqs  <span class="ot"><-</span> newDias (replicate (length rs) (square <span class="dv">2</span>) <span class="fu">#</span> fc orange)
<span class="ot">></span>   constrainWith vcat cirs
<span class="ot">></span>   zipWithM_ sameY cirs sqs
<span class="ot">></span>   constrainWith hcat [cirs <span class="fu">!!</span> <span class="dv">0</span>, sqs <span class="fu">!!</span> <span class="dv">0</span>]
<span class="ot">></span>   along (direction (<span class="dv">1</span> <span class="fu">^&</span> (<span class="fu">-</span><span class="dv">1</span>))) (map centerOf sqs)</code></pre></div></div></div><p>See the <a class="reference external" href="http://projects.haskell.org/diagrams/haddock/diagrams-contrib/Diagrams-TwoD-Layout-Constrained.html">package documentation</a> for more examples and documentation.</p></div><div class="section" id="anchors"><h2>Anchors</h2><p>Another new module in <span class="package"><a href="http://hackage.haskell.org/package/diagrams-contrib"><code>diagrams-contrib</code></a></span>,
<span class="module"><a href="http://projects.haskell.org/diagrams/haddock/Diagrams-Anchors.html"><code>Diagrams.Anchors</code></a></span>, provides a convenient interface for aligning
diagrams relative to named anchor points.  This can be useful, for
example, when laying out diagrams composed of pieces that should
"attach" to each other at various points.</p><p>We don't have an example of its use at the moment—if you play with
it and create a nice example, let us know!</p></div></div><div class="section" id="paths"><h1>Paths</h1><div class="section" id="boolean-path-operations"><h2>Boolean path operations</h2><p>The new <span class="module"><a href="http://projects.haskell.org/diagrams/haddock/Diagrams-TwoD-Path-Boolean.html"><code>Diagrams.TwoD.Path.Boolean</code></a></span> module from
<span class="package"><a href="http://hackage.haskell.org/package/diagrams-contrib"><code>diagrams-contrib</code></a></span> contains functions for computing boolean
combinations of paths, such as union, intersection, difference, and
symmetric difference.</p><div class="dia-lhs panel panel-default"><div class="panel-body"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/842ddb95b25d4e23.png" width="500" height="200" /></div><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> <span class="kw">import qualified</span> <span class="dt">Diagrams.TwoD.Path.Boolean</span> <span class="kw">as</span> <span class="dt">B</span>
<span class="ot">></span>
<span class="ot">></span> thing1,<span class="ot"> thing2 ::</span> <span class="dt">Path</span> <span class="dt">V2</span> <span class="dt">Double</span>
<span class="ot">></span> thing1 <span class="fu">=</span> square <span class="dv">1</span>
<span class="ot">></span> thing2 <span class="fu">=</span> circle <span class="fl">0.5</span> <span class="fu">#</span> translate (<span class="fl">0.5</span> <span class="fu">^&</span> (<span class="fu">-</span><span class="fl">0.5</span>))
<span class="ot">></span>
<span class="ot">></span> example <span class="fu">=</span> hsep <span class="fl">0.5</span> <span class="fu">.</span> fc green <span class="fu">.</span> map strokePath <span class="fu">$</span>
<span class="ot">></span>   [ B.union        <span class="dt">Winding</span> (thing1 <span class="fu"><></span> thing2)
<span class="ot">></span>   , B.intersection <span class="dt">Winding</span> thing1     thing2
<span class="ot">></span>   , B.difference   <span class="dt">Winding</span> thing1     thing2
<span class="ot">></span>   , B.exclusion    <span class="dt">Winding</span> thing1     thing2
<span class="ot">></span>   ]</code></pre></div></div></div></div><div class="section" id="cubic-b-splines"><h2>Cubic B-splines</h2><p><span class="module"><a href="http://projects.haskell.org/diagrams/haddock/Diagrams-CubicSpline.html"><code>Diagrams.CubicSpline</code></a></span> has a new function, <code class="sourceCode">bspline</code>, which
creates a smooth curve (to be precise, a [uniform cubic
B-spline](<a class="reference external" href="https://en.wikipedia.org/wiki/B-spline">https://en.wikipedia.org/wiki/B-spline</a>)) with the given
points as control points. The curve begins and ends at the first and
last points, and is tangent to the lines to the second-to-last control
points.  It does not, in general, pass through the intermediate
control points.</p><div class="dia-lhs panel panel-default"><div class="panel-body"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/06ce1d338b86a736.png" width="500" height="200" /></div><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> pts <span class="fu">=</span> map p2 (zip [<span class="dv">0</span> <span class="fu">..</span> <span class="dv">8</span>] (cycle [<span class="dv">0</span>, <span class="dv">1</span>]))
<span class="ot">></span> example <span class="fu">=</span> mconcat
<span class="ot">></span>   [ bspline pts
<span class="ot">></span>   , mconcat <span class="fu">$</span> map (place (circle <span class="fl">0.1</span> <span class="fu">#</span> fc blue <span class="fu">#</span> lw none)) pts
<span class="ot">></span>   ]</code></pre></div></div></div><p>One major difference between <code class="sourceCode">cubicSpline</code> and <code class="sourceCode">bspline</code> is that the
curves generated by <code class="sourceCode">cubicSpline</code> depend on the control points in a
global way—that is, changing one control point could alter the
entire curve—whereas with <code class="sourceCode">bspline</code>, each control point only affects
a local portion of the curve.</p></div><div class="section" id="following-composition"><h2>Following composition</h2><p><span class="package"><a href="http://hackage.haskell.org/package/diagrams-contrib"><code>diagrams-contrib</code></a></span> has a new module,
<span class="module"><a href="http://projects.haskell.org/diagrams/haddock/Diagrams-TwoD-Path-Follow.html"><code>Diagrams.TwoD.Path.Follow</code></a></span>, which defines a wrapper type
<code class="sourceCode"><span class="dt">Following</span> n</code>.  <code class="sourceCode"><span class="dt">Following</span></code> is just like <code class="sourceCode"><span class="dt">Trail'</span> <span class="dt">Line</span> <span class="dt">V2</span></code>, except that
it has a different <code class="sourceCode"><span class="dt">Monoid</span></code> instance: following values are
concatenated, just like regular lines, except that they are also
rotated so the tangents match at the join point. In addition, they are
normalized so the tangent at the start point is in the direction of
the positive \(x\) axis (essentially we are considering trails
equivalent up to rotation).</p><div class="dia-lhs panel panel-default"><div class="panel-body"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/87d7f30846d9e30a.png" width="500" height="200" /></div><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> <span class="kw">import </span><span class="dt">Control.Lens</span> (ala)
<span class="ot">></span> <span class="kw">import </span><span class="dt">Diagrams.TwoD.Path.Follow</span>
<span class="ot">></span>
<span class="ot">> wibble ::</span> <span class="dt">Trail'</span> <span class="dt">Line</span> <span class="dt">V2</span> <span class="dt">Double</span>
<span class="ot">></span> wibble <span class="fu">=</span> hrule <span class="dv">1</span> <span class="fu"><></span> hrule <span class="fl">0.5</span> <span class="fu">#</span> rotateBy (<span class="dv">1</span><span class="fu">/</span><span class="dv">6</span>) <span class="fu"><></span> hrule <span class="fl">0.5</span> <span class="fu">#</span> rotateBy (<span class="fu">-</span><span class="dv">1</span><span class="fu">/</span><span class="dv">6</span>) <span class="fu"><></span> a
<span class="ot">></span>   <span class="kw">where</span> a <span class="fu">=</span> arc (xDir <span class="fu">#</span> rotateBy (<span class="fu">-</span><span class="dv">1</span><span class="fu">/</span><span class="dv">4</span>)) (<span class="dv">1</span><span class="fu">/</span><span class="dv">5</span> <span class="fu">@@</span> turn)
<span class="ot">></span>           <span class="fu">#</span> scale <span class="fl">0.7</span>
<span class="ot">></span>
<span class="ot">></span> example <span class="fu">=</span>
<span class="ot">></span>   [ wibble
<span class="ot">></span>   , wibble
<span class="ot">></span>     <span class="fu">#</span> replicate <span class="dv">5</span>
<span class="ot">></span>     <span class="fu">#</span> ala follow foldMap
<span class="ot">></span>   ]
<span class="ot">></span>   <span class="fu">#</span> map stroke
<span class="ot">></span>   <span class="fu">#</span> map centerXY
<span class="ot">></span>   <span class="fu">#</span> hsep <span class="dv">1</span>
<span class="ot">></span>   <span class="fu">#</span> frame <span class="fl">0.3</span></code></pre></div></div></div><p>Notice how the above example makes use of the <code class="sourceCode">ala</code> combinator from
<code class="sourceCode"><span class="dt">Control.Lens</span></code> to automatically wrap all the <code class="sourceCode"><span class="dt">Line</span></code>s using <code class="sourceCode">follow</code>
before combining and then unwrap the result.</p></div></div><div class="section" id="fun"><h1>Fun</h1><div class="section" id="l-systems"><h2>L-systems</h2><p>The new module <span class="module"><a href="http://projects.haskell.org/diagrams/haddock/Diagrams-TwoD-Path-LSystem.html"><code>Diagrams.TwoD.Path.LSystem</code></a></span> in
<span class="package"><a href="http://hackage.haskell.org/package/diagrams-contrib"><code>diagrams-contrib</code></a></span> draws L-systems described by recursive string
rewriting rules, and provides a number of examples that can be used as
starting points for exploration.</p><div class="dia-lhs panel panel-default"><div class="panel-body"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/c669472f67c0a554.png" width="500" height="200" /></div><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> <span class="kw">import           </span><span class="dt">Diagrams.TwoD.Path.LSystem</span>
<span class="ot">></span> <span class="kw">import qualified</span> <span class="dt">Data.Map</span> <span class="kw">as</span> <span class="dt">M</span>
<span class="ot">></span>
<span class="ot">> tree ::</span> <span class="dt">RealFloat</span> n <span class="ot">=></span> <span class="dt">Int</span> <span class="ot">-></span> <span class="dt">TurtleState</span> n
<span class="ot">></span> tree n <span class="fu">=</span> lSystem n (<span class="dv">1</span><span class="fu">/</span><span class="dv">18</span> <span class="fu">@@</span> turn) (symbols <span class="st">"F"</span>) rules
<span class="ot">></span>  <span class="kw">where</span>
<span class="ot">></span>    rules  <span class="fu">=</span> M.fromList [rule <span class="ch">'F'</span> <span class="st">"F[+>>>F]F[->>>F][>>>F]"</span>]
<span class="ot">></span>
<span class="ot">></span> example <span class="fu">=</span> getTurtleDiagram <span class="fu">$</span> tree <span class="dv">6</span></code></pre></div></div></div><p>This example is already provided by the module as <code class="sourceCode">tree2</code>.</p></div><div class="section" id="xkcd-colors"><h2>XKCD colors</h2><p>Randall Munroe, of xkcd fame, ran a survey to determine commonly used
names for colors, and published a list of the 954 most common colors
based on the results.  <span class="module"><a href="http://projects.haskell.org/diagrams/haddock/Diagrams-Color-XKCD.html"><code>Diagrams.Color.XKCD</code></a></span> from
<span class="package"><a href="http://hackage.haskell.org/package/diagrams-contrib"><code>diagrams-contrib</code></a></span> provides all these color names.</p><div class="dia-lhs panel panel-default"><div class="panel-body"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/4dacb58d9aec6e70.png" width="500" height="200" /></div><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> <span class="kw">import </span><span class="dt">Diagrams.Color.XKCD</span>
<span class="ot">></span>
<span class="ot">></span> colors <span class="fu">=</span> [booger, poisonGreen, cinnamon, petrol, vibrantPurple]
<span class="ot">></span> example <span class="fu">=</span> hsep <span class="fl">0.1</span> (zipWith fcA colors (repeat (circle <span class="dv">1</span> <span class="fu">#</span> lw none)))</code></pre></div></div></div></div></div></div></div></div>

</div>]]></description>
    <pubDate>Tue, 03 Jan 2017 00:00:00 UT</pubDate>
    <guid>http://projects.haskell.org/diagrams/blog/2017-01-03-diagrams-1.4.html</guid>
    <dc:creator>diagrams contributors</dc:creator>
</item>
<item>
    <title>Diagrams + Cairo + Gtk + Mouse picking, Reloaded</title>
    <link>http://projects.haskell.org/diagrams/blog/2015-04-30-GTK-coordinates.html</link>
    <description><![CDATA[<div class="blog-header">
    <p>by <em>Brent Yorgey</em> on <strong>April 30, 2015</strong></p>
    <p>Tagged as: <a href="http://projects.haskell.org/diagrams/tags/cairo.html">cairo</a>, <a href="http://projects.haskell.org/diagrams/tags/GTK.html">GTK</a>, <a href="http://projects.haskell.org/diagrams/tags/mouse.html">mouse</a>, <a href="http://projects.haskell.org/diagrams/tags/coordinates.html">coordinates</a>, <a href="http://projects.haskell.org/diagrams/tags/transformation.html">transformation</a>, <a href="http://projects.haskell.org/diagrams/tags/features.html">features</a>, <a href="http://projects.haskell.org/diagrams/tags/1.3.html">1.3</a>.</p>
</div>

<div>
    <?xml version="1.0" encoding="UTF-8" ?>
<div class="container bs-docs-container"><div class="row"><div class="col-md-3"><div class="bs-sidebar hidden-print" role="complementary" data-spy="affix"></div></div><div class="col-md-9"><h1 class="title">Diagrams + Cairo + Gtk + Mouse picking, reloaded</h1><p>A little over a year ago, Christopher Mears wrote <a class="reference external" href="http://www.cmears.id.au/articles/diagrams-gtk-mouse.html">a nice article on
how to match up mouse clicks in a GTK window with parts of a
diagram</a>.  The only downside was that to make it work, you had to
explicitly construct the diagram in such a way that its coordinate
system precisely matched the coordinates of the window you wanted to
use, so that there was essentially no "translation" to do.  This was
unfortunate, since constructing a diagram in a particular global
coordinate system is not a very "diagrams-y" sort of thing to do.
However, the 1.3 release of diagrams includes a new feature that makes
matching up mouse clicks and diagrams much easier and more idiomatic,
and I thought it would be worth updating Chris's original example to
work more idiomatically in diagrams 1.3. The complete code is listed
at the end.</p><p>First, here's how we construct the house.  This is quite different
from the way Chris did it; I have tried to make it more idiomatic by
focusing on local relationships of constituent pieces, rather than
putting everything at absolute global coordinates.  We first create
all the constituent pieces:</p><div class="examplesrc"><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> <span class="co">-- The diagram to be drawn, with features tagged by strings.</span>
<span class="ot">> prettyHouse ::</span> <span class="dt">QDiagram</span> <span class="dt">Cairo</span> <span class="dt">V2</span> <span class="dt">Double</span> [<span class="dt">String</span>]
<span class="ot">></span> prettyHouse <span class="fu">=</span> house
<span class="ot">></span>   <span class="kw">where</span>
<span class="ot">></span>     roof    <span class="fu">=</span> triangle <span class="dv">1</span>   <span class="fu">#</span> scaleToY <span class="fl">0.75</span> <span class="fu">#</span> centerY <span class="fu">#</span> fc blue
<span class="ot">></span>     door    <span class="fu">=</span> rect <span class="fl">0.2</span> <span class="fl">0.4</span> <span class="fu">#</span> fc red
<span class="ot">></span>     handle  <span class="fu">=</span> circle <span class="fl">0.02</span>  <span class="fu">#</span> fc black
<span class="ot">></span>     wall    <span class="fu">=</span> square <span class="dv">1</span>     <span class="fu">#</span> fc yellow
<span class="ot">></span>     chimney <span class="fu">=</span> fromOffsets [<span class="dv">0</span> <span class="fu">^&</span> <span class="fl">0.25</span>, <span class="fl">0.1</span> <span class="fu">^&</span> <span class="dv">0</span>, <span class="dv">0</span> <span class="fu">^&</span> (<span class="fu">-</span><span class="fl">0.4</span>)]
<span class="ot">></span>             <span class="fu">#</span> closeTrail <span class="fu">#</span> strokeT <span class="fu">#</span> fc green
<span class="ot">></span>             <span class="fu">#</span> centerX
<span class="ot">></span>             <span class="fu">#</span> named <span class="st">"chimney"</span>
<span class="ot">></span>     smoke <span class="fu">=</span> mconcat
<span class="ot">></span>       [ circle <span class="fl">0.05</span> <span class="fu">#</span> translate v
<span class="ot">></span>       <span class="fu">|</span> v <span class="ot"><-</span> [ zero, <span class="fl">0.05</span> <span class="fu">^&</span> <span class="fl">0.15</span> ]
<span class="ot">></span>       ]
<span class="ot">></span>       <span class="fu">#</span> fc grey</code></pre></div></div><p>We then put the pieces together, labelling each by its name with the
<code class="sourceCode">value</code> function. Diagrams can be valuated by any monoid; when two
diagrams are combined, the value at each point will be the <code class="sourceCode">mappend</code>
of the values of the two component diagrams.  In this case, each point
in the final diagram will accumulate a list of <code class="sourceCode"><span class="dt">String</span></code>s
corresponding to the pieces of the house which are under that point.
Note how we make use of combinators like <code class="sourceCode">vcat</code> and <code class="sourceCode">mconcat</code>,
alignments like <code class="sourceCode">alignB</code>, <code class="sourceCode">snugL</code> and <code class="sourceCode">snugR</code>, and the use of a named
subdiagram (the chimney) to position the components relative to each
other. (You can click on any of the above function names to go to
their documentation!)</p><div class="examplesrc"><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span>     house <span class="fu">=</span> vcat
<span class="ot">></span>       [ mconcat
<span class="ot">></span>         [ roof    <span class="fu">#</span> snugR                   <span class="fu">#</span> value [<span class="st">"roof"</span>]
<span class="ot">></span>         , chimney <span class="fu">#</span> snugL                   <span class="fu">#</span> value [<span class="st">"chimney"</span>]
<span class="ot">></span>         ]
<span class="ot">></span>         <span class="fu">#</span> centerX
<span class="ot">></span>       , mconcat
<span class="ot">></span>         [ handle  <span class="fu">#</span> translate (<span class="fl">0.05</span> <span class="fu">^&</span> <span class="fl">0.2</span>) <span class="fu">#</span> value [<span class="st">"handle"</span>]
<span class="ot">></span>         , door    <span class="fu">#</span> alignB                  <span class="fu">#</span> value [<span class="st">"door"</span>]
<span class="ot">></span>         , wall    <span class="fu">#</span> alignB                  <span class="fu">#</span> value [<span class="st">"wall"</span>]
<span class="ot">></span>         ]
<span class="ot">></span>       ]
<span class="ot">></span>       <span class="fu">#</span> withName <span class="st">"chimney"</span> (\chim <span class="ot">-></span>
<span class="ot">></span>           atop (smoke <span class="fu">#</span> moveTo (location chim) <span class="fu">#</span> translateY <span class="fl">0.4</span>
<span class="ot">></span>                       <span class="fu">#</span> value [<span class="st">"smoke"</span>]
<span class="ot">></span>                )
<span class="ot">></span>         )</code></pre></div></div><div class="exampleimg"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/37edfa0badeed824.png" width="500" height="200" /></div></div><p>Now, when we render the diagram to a GTK window, we can get diagrams
to give us an affine transformation that mediates between the
diagram's local coordinates and the GTK window's coordinates.  I'll
just highlight a few pieces of the code; the complete listing can be
found at the end of the post.  We first create an <code>IORef</code> to hold
the transformation:</p><div class="examplesrc"><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span>   gtk2DiaRef <span class="ot"><-</span> (newIORef<span class="ot"> mempty ::</span> <span class="dt">IO</span> (<span class="dt">IORef</span> (<span class="dt">T2</span> <span class="dt">Double</span>)))</code></pre></div></div><p>We initialize it with the identity transformation.  We use the
<code class="sourceCode">renderDiaT</code> function to get not only a rendering action but also the
transformation from diagram to GTK coordinates; we save the inverse of
the transformation in the <code>IORef</code> (since we will want to convert
from GTK to diagram coordinates):</p><div class="examplesrc"><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span>     <span class="kw">let</span> (dia2gtk, (_,r)) <span class="fu">=</span> renderDiaT <span class="dt">Cairo</span>
<span class="ot">></span>                              (<span class="dt">CairoOptions</span> <span class="st">""</span> (mkWidth <span class="dv">250</span>) <span class="dt">PNG</span> <span class="dt">False</span>)
<span class="ot">></span>                              prettyHouse
<span class="ot">></span>
<span class="ot">></span>     <span class="co">-- store the inverse of the diagram -> window coordinate transformation</span>
<span class="ot">></span>     <span class="co">-- for later use in interpreting mouse clicks</span>
<span class="ot">></span>     writeIORef gtk2DiaRef (inv dia2gtk)</code></pre></div></div><p>(Note that if it is possible for the first motion notify event to
happen before the expose event, then such mouse motions will be
computed to correspond to the wrong part of the diagram, but who
cares.)  Now, when we receive a mouse click, we apply the stored
transformation to convert to a point in diagram coordinates, and pass
it to the <code class="sourceCode">sample</code> function to extract a list of house components at
that location.</p><div class="examplesrc"><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span>     (x,y) <span class="ot"><-</span> eventCoordinates
<span class="ot">></span>
<span class="ot">></span>     <span class="co">-- transform the mouse click back into diagram coordinates.</span>
<span class="ot">></span>     gtk2Dia <span class="ot"><-</span> liftIO <span class="fu">$</span> readIORef gtk2DiaRef
<span class="ot">></span>     <span class="kw">let</span> pt' <span class="fu">=</span> transform gtk2Dia (p2 (x,y))
<span class="ot">></span>
<span class="ot">></span>     liftIO <span class="fu">$</span> <span class="kw">do</span>
<span class="ot">></span>       putStrLn <span class="fu">$</span> show (x,y) <span class="fu">++</span> <span class="st">": "</span>
<span class="ot">></span>                    <span class="fu">++</span> intercalate <span class="st">" "</span> (sample prettyHouse pt')</code></pre></div></div><p>The final product ends up looking and behaving identically to the
<a class="reference external" href="https://www.youtube.com/watch?v=vwf9aVdDipo">video that Chris made</a>.</p><p>Finally, here's the complete code.  A lot of it is just boring
standard GTK setup.</p><div class="examplesrc"><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> <span class="kw">import           </span><span class="dt">Control.Monad</span>                   (void)
<span class="ot">></span> <span class="kw">import           </span><span class="dt">Control.Monad.IO.Class</span>          (liftIO)
<span class="ot">></span> <span class="kw">import           </span><span class="dt">Data.IORef</span>
<span class="ot">></span> <span class="kw">import           </span><span class="dt">Data.List</span>                       (intercalate)
<span class="ot">></span> <span class="kw">import           </span><span class="dt">Diagrams.Backend.Cairo</span>
<span class="ot">></span> <span class="kw">import           </span><span class="dt">Diagrams.Backend.Cairo.Internal</span>
<span class="ot">></span> <span class="kw">import           </span><span class="dt">Diagrams.Prelude</span>
<span class="ot">></span> <span class="kw">import           </span><span class="dt">Graphics.UI.Gtk</span>
<span class="ot">></span>
<span class="ot">> main ::</span> <span class="dt">IO</span> ()
<span class="ot">></span> main <span class="fu">=</span> <span class="kw">do</span>
<span class="ot">></span>   <span class="co">-- Ordinary Gtk setup.</span>
<span class="ot">></span>   void initGUI
<span class="ot">></span>   w <span class="ot"><-</span> windowNew
<span class="ot">></span>   da <span class="ot"><-</span> drawingAreaNew
<span class="ot">></span>   w <span class="ot">`containerAdd`</span> da
<span class="ot">></span>   void <span class="fu">$</span> w <span class="ot">`on`</span> deleteEvent <span class="fu">$</span> liftIO mainQuit <span class="fu">>></span> return <span class="dt">True</span>
<span class="ot">></span>
<span class="ot">></span>   <span class="co">-- Make an IORef to hold the transformation from window to diagram</span>
<span class="ot">></span>   <span class="co">-- coordinates.</span>
<span class="ot">></span>   gtk2DiaRef <span class="ot"><-</span> (newIORef<span class="ot"> mempty ::</span> <span class="dt">IO</span> (<span class="dt">IORef</span> (<span class="dt">T2</span> <span class="dt">Double</span>)))
<span class="ot">></span>
<span class="ot">></span>   <span class="co">-- Render the diagram on the drawing area and save the transformation.</span>
<span class="ot">></span>   void <span class="fu">$</span> da <span class="ot">`on`</span> exposeEvent <span class="fu">$</span> liftIO <span class="fu">$</span> <span class="kw">do</span>
<span class="ot">></span>     dw <span class="ot"><-</span> widgetGetDrawWindow da
<span class="ot">></span>
<span class="ot">></span>     <span class="co">-- renderDiaT returns both a rendering result as well as the</span>
<span class="ot">></span>     <span class="co">-- transformation from diagram to output coordinates.</span>
<span class="ot">></span>     <span class="kw">let</span> (dia2gtk, (_,r)) <span class="fu">=</span> renderDiaT <span class="dt">Cairo</span>
<span class="ot">></span>                              (<span class="dt">CairoOptions</span> <span class="st">""</span> (mkWidth <span class="dv">250</span>) <span class="dt">PNG</span> <span class="dt">False</span>)
<span class="ot">></span>                              prettyHouse
<span class="ot">></span>
<span class="ot">></span>     <span class="co">-- store the inverse of the diagram -> window coordinate transformation</span>
<span class="ot">></span>     <span class="co">-- for later use in interpreting mouse clicks</span>
<span class="ot">></span>     writeIORef gtk2DiaRef (inv dia2gtk)
<span class="ot">></span>
<span class="ot">></span>     renderWithDrawable dw r
<span class="ot">></span>     return <span class="dt">True</span>
<span class="ot">></span>
<span class="ot">></span>   <span class="co">-- When the mouse moves, show the coordinates and the objects under</span>
<span class="ot">></span>   <span class="co">-- the pointer.</span>
<span class="ot">></span>   void <span class="fu">$</span> da <span class="ot">`on`</span> motionNotifyEvent <span class="fu">$</span> <span class="kw">do</span>
<span class="ot">></span>     (x,y) <span class="ot"><-</span> eventCoordinates
<span class="ot">></span>
<span class="ot">></span>     <span class="co">-- transform the mouse click back into diagram coordinates.</span>
<span class="ot">></span>     gtk2Dia <span class="ot"><-</span> liftIO <span class="fu">$</span> readIORef gtk2DiaRef
<span class="ot">></span>     <span class="kw">let</span> pt' <span class="fu">=</span> transform gtk2Dia (p2 (x,y))
<span class="ot">></span>
<span class="ot">></span>     liftIO <span class="fu">$</span> <span class="kw">do</span>
<span class="ot">></span>       putStrLn <span class="fu">$</span> show (x,y) <span class="fu">++</span> <span class="st">": "</span>
<span class="ot">></span>                    <span class="fu">++</span> intercalate <span class="st">" "</span> (sample prettyHouse pt')
<span class="ot">></span>       return <span class="dt">True</span>
<span class="ot">></span>
<span class="ot">></span>   <span class="co">-- Run the Gtk main loop.</span>
<span class="ot">></span>   da <span class="ot">`widgetAddEvents`</span> [<span class="dt">PointerMotionMask</span>]
<span class="ot">></span>   widgetShowAll w
<span class="ot">></span>   mainGUI
<span class="ot">></span>
<span class="ot">></span> <span class="co">-- The diagram to be drawn, with features tagged by strings.</span>
<span class="ot">> prettyHouse ::</span> <span class="dt">QDiagram</span> <span class="dt">Cairo</span> <span class="dt">V2</span> <span class="dt">Double</span> [<span class="dt">String</span>]
<span class="ot">></span> prettyHouse <span class="fu">=</span> house
<span class="ot">></span>   <span class="kw">where</span>
<span class="ot">></span>     roof    <span class="fu">=</span> triangle <span class="dv">1</span>   <span class="fu">#</span> scaleToY <span class="fl">0.75</span> <span class="fu">#</span> centerY <span class="fu">#</span> fc blue
<span class="ot">></span>     door    <span class="fu">=</span> rect <span class="fl">0.2</span> <span class="fl">0.4</span> <span class="fu">#</span> fc red
<span class="ot">></span>     handle  <span class="fu">=</span> circle <span class="fl">0.02</span>  <span class="fu">#</span> fc black
<span class="ot">></span>     wall    <span class="fu">=</span> square <span class="dv">1</span>     <span class="fu">#</span> fc yellow
<span class="ot">></span>     chimney <span class="fu">=</span> fromOffsets [<span class="dv">0</span> <span class="fu">^&</span> <span class="fl">0.25</span>, <span class="fl">0.1</span> <span class="fu">^&</span> <span class="dv">0</span>, <span class="dv">0</span> <span class="fu">^&</span> (<span class="fu">-</span><span class="fl">0.4</span>)]
<span class="ot">></span>             <span class="fu">#</span> closeTrail <span class="fu">#</span> strokeT <span class="fu">#</span> fc green
<span class="ot">></span>             <span class="fu">#</span> centerX
<span class="ot">></span>             <span class="fu">#</span> named <span class="st">"chimney"</span>
<span class="ot">></span>     smoke <span class="fu">=</span> mconcat
<span class="ot">></span>       [ circle <span class="fl">0.05</span> <span class="fu">#</span> translate v
<span class="ot">></span>       <span class="fu">|</span> v <span class="ot"><-</span> [ zero, <span class="fl">0.05</span> <span class="fu">^&</span> <span class="fl">0.15</span> ]
<span class="ot">></span>       ]
<span class="ot">></span>       <span class="fu">#</span> fc grey
<span class="ot">></span>     house <span class="fu">=</span> vcat
<span class="ot">></span>       [ mconcat
<span class="ot">></span>         [ roof    <span class="fu">#</span> snugR                  <span class="fu">#</span> value [<span class="st">"roof"</span>]
<span class="ot">></span>         , chimney <span class="fu">#</span> snugL                  <span class="fu">#</span> value [<span class="st">"chimney"</span>]
<span class="ot">></span>         ]
<span class="ot">></span>         <span class="fu">#</span> centerX
<span class="ot">></span>       , mconcat
<span class="ot">></span>         [ handle  <span class="fu">#</span> translate (<span class="fl">0.05</span> <span class="fu">^&</span> <span class="fl">0.2</span>) <span class="fu">#</span> value [<span class="st">"handle"</span>]
<span class="ot">></span>         , door    <span class="fu">#</span> alignB                  <span class="fu">#</span> value [<span class="st">"door"</span>]
<span class="ot">></span>         , wall    <span class="fu">#</span> alignB                  <span class="fu">#</span> value [<span class="st">"wall"</span>]
<span class="ot">></span>         ]
<span class="ot">></span>       ]
<span class="ot">></span>       <span class="fu">#</span> withName <span class="st">"chimney"</span> (\chim <span class="ot">-></span>
<span class="ot">></span>           atop (smoke <span class="fu">#</span> moveTo (location chim) <span class="fu">#</span> translateY <span class="fl">0.4</span>
<span class="ot">></span>                       <span class="fu">#</span> value [<span class="st">"smoke"</span>]
<span class="ot">></span>                )
<span class="ot">></span>         )</code></pre></div></div></div></div></div>

</div>]]></description>
    <pubDate>Thu, 30 Apr 2015 00:00:00 UT</pubDate>
    <guid>http://projects.haskell.org/diagrams/blog/2015-04-30-GTK-coordinates.html</guid>
    <dc:creator>diagrams contributors</dc:creator>
</item>
<item>
    <title>Diagrams 1.3</title>
    <link>http://projects.haskell.org/diagrams/blog/2015-04-24-diagrams-1.3.html</link>
    <description><![CDATA[<div class="blog-header">
    <p>by <em>Brent Yorgey</em> on <strong>April 25, 2015</strong></p>
    <p>Tagged as: <a href="http://projects.haskell.org/diagrams/tags/release.html">release</a>, <a href="http://projects.haskell.org/diagrams/tags/features.html">features</a>, <a href="http://projects.haskell.org/diagrams/tags/announcement.html">announcement</a>, <a href="http://projects.haskell.org/diagrams/tags/1.3.html">1.3</a>.</p>
</div>

<div>
    <?xml version="1.0" encoding="UTF-8" ?>
<div class="container bs-docs-container"><div class="row"><div class="col-md-3"><div class="bs-sidebar hidden-print" role="complementary" data-spy="affix"></div></div><div class="col-md-9"><h1 class="title">Diagrams 1.3</h1><p>The diagrams team is very pleased to announce the release of diagrams
1.3.  The actual release to Hackage happened a week or so ago, and by
now I think we have most of the little kinks ironed out.  This is an
exciting release that represents a great deal of effort from a lot of
people (see the list of contributors at the end of this post).  Here's
a quick rundown of some of the new features.  If you're just looking
for help porting your diagrams code to work with 1.3, see the
<a class="reference external" href="https://wiki.haskell.org/Diagrams/Dev/Migrate1.3">migration guide</a>.</p><div class="section" id="path-intersection"><h1>Path intersection</h1><p>Using the functions <code class="sourceCode">intersectPointsP</code> and <code class="sourceCode">intersectPointsT</code>, it is
now possible to find the points of intersection between two paths or
two trails, respectively.  This is not so hard for paths with straight
segments, but for cubic Bezier curves, finding intersection points is
nontrivial!</p><div class="dia-lhs panel panel-default"><div class="panel-body"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/53b7dfdadc9debac.png" width="500" height="200" /></div><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> <span class="ot">{-# LANGUAGE TupleSections #-}</span>
<span class="ot">></span>
<span class="ot">> example ::</span> <span class="dt">Diagram</span> <span class="dt">B</span>
<span class="ot">></span> example <span class="fu">=</span> mconcat (map (place pt) points) <span class="fu"><></span> mconcat ellipses
<span class="ot">></span>   <span class="kw">where</span>
<span class="ot">></span>     ell <span class="fu">=</span> circle <span class="dv">1</span> <span class="fu">#</span> scaleX <span class="dv">2</span>
<span class="ot">></span>     pt  <span class="fu">=</span> circle <span class="fl">0.05</span> <span class="fu">#</span> fc blue <span class="fu">#</span> lw none
<span class="ot">></span>     ellipses <span class="fu">=</span> [ ell <span class="fu">#</span> rotateBy r <span class="fu">#</span> translateX (<span class="dv">2</span><span class="fu">*</span>r) <span class="fu">|</span> r <span class="ot"><-</span> [<span class="dv">0</span>, <span class="dv">1</span><span class="fu">/</span><span class="dv">12</span> <span class="fu">..</span> <span class="dv">5</span><span class="fu">/</span><span class="dv">12</span>] ]
<span class="ot">></span>     points <span class="fu">=</span> allPairs ellipses <span class="fu">>>=</span> uncurry (intersectPointsP' 1e<span class="fu">-</span><span class="dv">8</span>)
<span class="ot">></span>     allPairs [] <span class="fu">=</span> []
<span class="ot">></span>     allPairs (x<span class="fu">:</span>xs) <span class="fu">=</span> map (x,) xs <span class="fu">++</span> allPairs xs</code></pre></div></div></div><p>Note that this feature is something of a "technology preview" in
diagrams 1.3: the API will probably change and grow in the next
release (for example, giving a way to find the <em>parameters</em> of
intersection points).</p></div><div class="section" id="affine-maps-and-projections"><h1>Affine maps and projections</h1><p>Affine maps have been added to <span class="module"><a href="http://projects.haskell.org/diagrams/haddock/Diagrams-LinearMap.html"><code>Diagrams.LinearMap</code></a></span> that can map
between <em>different</em> vector spaces. The <span class="module"><a href="http://projects.haskell.org/diagrams/haddock/Deformable.html"><code>Deformable</code></a></span> class has
also been generalised to map between spaces. Helper functions have
been added to <span class="module"><a href="http://projects.haskell.org/diagrams/haddock/Diagrams-ThreeD-Projection.html"><code>Diagrams.ThreeD.Projection</code></a></span> for basic orthographic
and perspective projections.</p><p>In the below example, we construct a 3-dimensional path representing
the wireframe of a simple house, and then project it into 2 dimensions
using perspective, orthographic, and isometric projections.</p><div class="dia-lhs panel panel-default"><div class="panel-body"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/7c1f2b73130edf93.png" width="500" height="200" /></div><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> <span class="kw">import </span><span class="dt">Diagrams.ThreeD.Transform</span>  (translateZ)
<span class="ot">></span> <span class="kw">import </span><span class="dt">Diagrams.ThreeD.Projection</span>
<span class="ot">></span> <span class="kw">import </span><span class="dt">Diagrams.LinearMap</span>         (amap)
<span class="ot">></span> <span class="kw">import </span><span class="dt">Linear.Matrix</span>              ((!*!))
<span class="ot">></span>
<span class="ot">> box ::</span> <span class="dt">Path</span> <span class="dt">V3</span> <span class="dt">Double</span>
<span class="ot">></span> box <span class="fu">=</span> <span class="dt">Path</span> [f p1 <span class="fu">~~</span> f p2 <span class="fu">|</span> p1 <span class="ot"><-</span> ps, p2 <span class="ot"><-</span> ps, quadrance (p1 <span class="fu">.-.</span> p2) <span class="fu">==</span> <span class="dv">4</span>]
<span class="ot">></span>   <span class="kw">where</span>
<span class="ot">></span>     ps <span class="fu">=</span> getAllCorners <span class="fu">$</span> fromCorners (<span class="fu">-</span><span class="dv">1</span>) <span class="dv">1</span>
<span class="ot">></span>     f  <span class="fu">=</span> fmap fromIntegral
<span class="ot">></span>
<span class="ot">> roof ::</span> <span class="dt">Path</span> <span class="dt">V3</span> <span class="dt">Double</span>
<span class="ot">></span> roof <span class="fu">=</span> <span class="dt">Path</span>
<span class="ot">></span>   [ mkP3 <span class="dv">1</span> <span class="dv">1</span> <span class="dv">1</span>       <span class="fu">~~</span> mkP3 <span class="dv">1</span> <span class="dv">0</span> <span class="fl">1.4</span>
<span class="ot">></span>   , mkP3 <span class="dv">1</span> (<span class="fu">-</span><span class="dv">1</span>) <span class="dv">1</span>    <span class="fu">~~</span> mkP3 <span class="dv">1</span> <span class="dv">0</span> <span class="fl">1.4</span>
<span class="ot">></span>   , mkP3 <span class="dv">1</span> <span class="dv">0</span> <span class="fl">1.4</span>     <span class="fu">~~</span> mkP3 (<span class="fu">-</span><span class="dv">1</span>) <span class="dv">0</span> <span class="fl">1.4</span>
<span class="ot">></span>   , mkP3 (<span class="fu">-</span><span class="dv">1</span>) <span class="dv">1</span> <span class="dv">1</span>    <span class="fu">~~</span> mkP3 (<span class="fu">-</span><span class="dv">1</span>) <span class="dv">0</span> <span class="fl">1.4</span>
<span class="ot">></span>   , mkP3 (<span class="fu">-</span><span class="dv">1</span>) (<span class="fu">-</span><span class="dv">1</span>) <span class="dv">1</span> <span class="fu">~~</span> mkP3 (<span class="fu">-</span><span class="dv">1</span>) <span class="dv">0</span> <span class="fl">1.4</span>
<span class="ot">></span>   ]
<span class="ot">></span>
<span class="ot">> door ::</span> <span class="dt">Path</span> <span class="dt">V3</span> <span class="dt">Double</span>
<span class="ot">></span> door <span class="fu">=</span> fromVertices
<span class="ot">></span>   [ mkP3 <span class="dv">1</span> (<span class="fu">-</span><span class="fl">0.2</span>) (<span class="fu">-</span><span class="dv">1</span>)
<span class="ot">></span>   , mkP3 <span class="dv">1</span> (<span class="fu">-</span><span class="fl">0.2</span>) (<span class="fu">-</span><span class="fl">0.4</span>)
<span class="ot">></span>   , mkP3 <span class="dv">1</span> (<span class="fl">0.2</span>) (<span class="fu">-</span><span class="fl">0.4</span>)
<span class="ot">></span>   , mkP3 <span class="dv">1</span> (<span class="fl">0.2</span>) (<span class="fu">-</span><span class="dv">1</span>)
<span class="ot">></span>   ]
<span class="ot">></span>
<span class="ot">></span> house <span class="fu">=</span> door <span class="fu"><></span> roof <span class="fu"><></span> box
<span class="ot">></span>
<span class="ot">></span> <span class="co">-- Perspective projection</span>
<span class="ot">></span> <span class="co">-- these bits are from Linear.Projection</span>
<span class="ot">></span> m  <span class="fu">=</span> lookAt (<span class="dt">V3</span> <span class="fl">3.4</span> <span class="dv">4</span> <span class="fl">2.2</span>) zero unitZ
<span class="ot">></span> pm <span class="fu">=</span> perspective (pi<span class="fu">/</span><span class="dv">3</span>) <span class="fl">0.8</span> <span class="dv">1</span> <span class="dv">3</span> <span class="fu">!*!</span> m
<span class="ot">></span>
<span class="ot">></span> pd <span class="fu">=</span> m44Deformation pm
<span class="ot">></span> perspectiveHouse <span class="fu">=</span> stroke <span class="fu">$</span> deform pd (translateZ (<span class="fu">-</span><span class="dv">1</span>) house)
<span class="ot">></span>
<span class="ot">></span> <span class="co">-- Orthogonal projection</span>
<span class="ot">></span> am <span class="fu">=</span> lookingAt (mkP3 <span class="fl">3.4</span> <span class="dv">4</span> <span class="fl">2.2</span>) zero zDir
<span class="ot">></span> orthogonalHouse <span class="fu">=</span> stroke <span class="fu">$</span> amap am house
<span class="ot">></span>
<span class="ot">></span> <span class="co">-- Isometric projection (specialised orthogonal)</span>
<span class="ot">></span> isometricHouse <span class="fu">=</span> stroke <span class="fu">$</span> isometricApply zDir house
<span class="ot">></span>
<span class="ot">> example ::</span> <span class="dt">Diagram</span> <span class="dt">B</span>
<span class="ot">></span> example <span class="fu">=</span> hsep <span class="dv">1</span> <span class="fu">.</span> map (sized (mkHeight <span class="dv">3</span>) <span class="fu">.</span> centerXY) <span class="fu">$</span>
<span class="ot">></span>   [ perspectiveHouse, orthogonalHouse, isometricHouse ]</code></pre></div></div></div><p>Note that this should also be considered a "technology preview".
Future releases of diagrams will likely include higher-level ways to
do projections.</p></div><div class="section" id="grouping-for-opacity"><h1>Grouping for opacity</h1><p>A few backends (<span class="package"><a href="http://hackage.haskell.org/package/diagrams-svg"><code>diagrams-svg</code></a></span>, <span class="package"><a href="http://hackage.haskell.org/package/diagrams-pgf"><code>diagrams-pgf</code></a></span>, and
<span class="package"><a href="http://hackage.haskell.org/package/diagrams-rasterific"><code>diagrams-rasterific</code></a></span> as of version 1.3.1) support <em>grouped
transparency</em>.  The idea is that transparency can be applied to <em>a
group of diagrams as a whole</em> rather than to individual diagrams.  The
difference is in what happens when diagrams overlap: if they are
individually transparent, the overlapping section will be darker, as
if two pieces of colored cellophane were overlapped.  If transparency
is applied to a group instead, the transparency is uniformly applied
to the rendered output of the group of diagrams, as if a single piece
of colored cellophane were cut out in the shape of the group of
diagrams.</p><p>An example should help make this clear.  In the example to the left
below, the section where the two transparent circles overlap is
darker.  On the right, the call to <code class="sourceCode">groupOpacity</code> means that the
entire shape formed form the union of the two circles is given a
uniform opacity; there is no darker region where the circles overlap.</p><div class="dia-lhs panel panel-default"><div class="panel-body"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/1e4dc4eb4637abc7.png" width="500" height="200" /></div><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> cir <span class="fu">=</span> circle <span class="dv">1</span> <span class="fu">#</span> lw none <span class="fu">#</span> fc red
<span class="ot">></span> overlap <span class="fu">=</span> (cir <span class="fu"><></span> cir <span class="fu">#</span> translateX <span class="dv">1</span>)
<span class="ot">></span>
<span class="ot">></span> example <span class="fu">=</span> hsep <span class="dv">1</span> [ overlap <span class="fu">#</span> opacity <span class="fl">0.3</span>, overlap <span class="fu">#</span> opacityGroup <span class="fl">0.3</span> ]
<span class="ot">></span>           <span class="fu">#</span> centerX
<span class="ot">></span>        <span class="fu"><></span> rect <span class="dv">9</span> <span class="fl">0.1</span> <span class="fu">#</span> fc lightblue <span class="fu">#</span> lw none</code></pre></div></div></div></div><div class="section" id="visualizing-envelopes-and-traces"><h1>Visualizing envelopes and traces</h1><p>Some new functions have been added to help visualize (approximations
of) the <a class="reference external" href="http://projects.haskell.org/diagrams/doc/manual.html#envelopes-and-local-vector-spaces">envelope</a> and <a class="reference external" href="http://projects.haskell.org/diagrams/doc/manual.html#traces">trace</a> of a diagram.  For example:</p><div class="dia-lhs panel panel-default"><div class="panel-body"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/3244e52088b4bb59.png" width="500" height="200" /></div><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> d1,<span class="ot"> d2 ::</span> <span class="dt">Diagram</span> <span class="dt">B</span>
<span class="ot">></span> d1 <span class="fu">=</span> circle <span class="dv">1</span>
<span class="ot">></span> d2 <span class="fu">=</span> (pentagon <span class="dv">1</span> <span class="fu">===</span> roundedRect <span class="fl">1.5</span> <span class="fl">0.7</span> <span class="fl">0.3</span>)
<span class="ot">></span>
<span class="ot">></span> example <span class="fu">=</span> hsep <span class="dv">1</span>
<span class="ot">></span>   [ (d1 <span class="fu">|||</span> d2)          <span class="fu">#</span> showEnvelope' (with <span class="fu">&</span> ePoints <span class="fu">.~</span> <span class="dv">360</span>) <span class="fu">#</span> showOrigin
<span class="ot">></span>   , (d1 <span class="fu">|||</span> d2) <span class="fu">#</span> center <span class="fu">#</span> showEnvelope' (with <span class="fu">&</span> ePoints <span class="fu">.~</span> <span class="dv">360</span>) <span class="fu">#</span> showOrigin
<span class="ot">></span>   , (d1 <span class="fu">|||</span> d2) <span class="fu">#</span> center <span class="fu">#</span> showTrace' (with <span class="fu">&</span> tPoints <span class="fu">.~</span> <span class="dv">20</span>) <span class="fu">#</span> showOrigin
<span class="ot">></span>   ]</code></pre></div></div></div></div><div class="section" id="better-command-line-looping"><h1>Better command-line looping</h1><p>For some time, many diagrams backends have had a "looped compilation
mode", where the diagram-rendering executables produced take a
<code>--loop</code> option, causing them to watch for changes to a source file,
recompile and relaunch themselves.  Support for this feature is now
greatly improved. We have switched to use <span class="package"><a href="http://hackage.haskell.org/package/fsnotify"><code>fsnotify</code></a></span>, which
eliminates polling and allows the feature to work on Windows for the
first time (previous versions depended on the <span class="package"><a href="http://hackage.haskell.org/package/unix"><code>unix</code></a></span> package).
The output of the <code>--loop</code> mode has also been improved.</p></div><div class="section" id="new-backends"><h1>New backends</h1><p>The <span class="package"><a href="http://hackage.haskell.org/package/diagrams-postscript"><code>diagrams-postscript</code></a></span>, <span class="package"><a href="http://hackage.haskell.org/package/diagrams-svg"><code>diagrams-svg</code></a></span>,
<span class="package"><a href="http://hackage.haskell.org/package/diagrams-cairo"><code>diagrams-cairo</code></a></span>, <span class="package"><a href="http://hackage.haskell.org/package/diagrams-gtk"><code>diagrams-gtk</code></a></span>, and
<span class="package"><a href="http://hackage.haskell.org/package/diagrams-rasterific"><code>diagrams-rasterific</code></a></span> backends are all still going strong and
fully supported.  We now have several new backends as well:
<span class="package"><a href="http://hackage.haskell.org/package/diagrams-html5"><code>diagrams-html5</code></a></span> generates Javascript which sets up an HTML5
canvas containing the diagram; <span class="package"><a href="http://hackage.haskell.org/package/diagrams-canvas"><code>diagrams-canvas</code></a></span> also targets
HTML5 canvas, but uses the <span class="package"><a href="http://hackage.haskell.org/package/blank-canvas"><code>blank-canvas</code></a></span> package to interact
directly with an HTML5 canvas, enabling various sorts of
interactivity.  We also have a new backend <span class="package"><a href="http://hackage.haskell.org/package/diagrams-pgf"><code>diagrams-pgf</code></a></span> which
generates PGF/TikZ code suitable for including in \(\TeX\)
documents—one can even have embedded text in diagrams typeset by
\(\TeX\), allowing <em>e.g.</em> mathematical formulas as labels for
things in your diagram.</p></div><div class="section" id="generalized-numerics"><h1>Generalized numerics</h1><p>It used to be that diagrams were hard-coded to use <code>Double</code>.  As of
version 1.3, <code>Double</code> is no longer baked in: diagrams are now
parameterized by a suitable numeric type.  It's too early to tell what
the full implications of this will be, but in theory it opens up
opportunities for things like automatic differentiation, constraint
solving, and using diagrams in conjunction with deeply embedded DSLs.</p><p>This feature in particular was a tough nut to crack and is the fruit
of a lot of labor.  I want to especially highlight the work of Jan
Bracker, Allan Gardner, and Frank Staals, all of whom did a lot of
work attempting to generalize diagrams in this way.  Although their
code ultimately did not get merged, we learned a lot from their
attempts!  The fourth attempt, by Chris Chalmers, actually stuck. A
big factor in his success was to simultaneously replace the
<span class="package"><a href="http://hackage.haskell.org/package/vector-space"><code>vector-space</code></a></span> package with <span class="package"><a href="http://hackage.haskell.org/package/linear"><code>linear</code></a></span>, which turns out to
work very nicely with diagrams and with generalized numeric types in
particular.</p><p>Note that this is a Very Breaking Change as the types of almost
everything changed.  Anything which used to take a single type
representing a vector space (such as <code class="sourceCode"><span class="dt">R2</span></code>) as an argument now takes
two arguments, one for the structure/dimension of the vector space
(<em>e.g.</em> <code class="sourceCode"><span class="dt">V2</span></code>) and one for the numeric/scalar type.  See the <a class="reference external" href="https://wiki.haskell.org/Diagrams/Dev/Migrate1.3">migration
guide</a> for more specific information and help upgrading!</p></div><div class="section" id="and-lots-more"><h1>And lots more...</h1><p>Of course, there are lots of other miscellaneous improvements, added
type class instances, new lenses and prisms, bug fixes, and the like.
For a full rundown see the <a class="reference external" href="http://projects.haskell.org/diagrams/releases.html">release notes</a>.  There is also lots more
exciting stuff in the pipeline!</p></div><div class="section" id="contributors"><h1>Contributors</h1><p>We now have a team of 5 people working very actively on diagrams
(Chris Chalmers, Daniel Bergey, Jeff Rosenbluth, Ryan Yates, and
myself), with many, many more contributing here and there.  As a way
to say thank you for all the great contributions and hard work by many
in the community, below is a (probably incomplete) list of people who
have contributed to diagrams in some way — all 67 of them!  We
<a class="reference external" href="http://projects.haskell.org/diagrams/community.html">welcome involvement</a> from anyone, regardless of experience.  If you'd
like to get involved, come chat with us on the <a class="reference external" href="http://webchat.freenode.net/?channels=diagrams">#diagrams IRC channel</a>
on freenode, or send a message to the <a class="reference external" href="http://groups.google.com/group/diagrams-discuss">mailing list</a>.</p><p>Diagrams contributors:</p><p>Alexis Praga /
Allan Gardner /
Andy Gill /
Anthony Cowley /
Bartosz Nitka /
Ben Gamari /
Brent Yorgey /
Carlos Scheidegger /
Carter Tazio Schonwald /
Chris Mears /
Christopher Chalmers /
Claude Heiland-Allen /
Conal Elliott /
Daniel Bergey /
Daniel Kröni /
Daniel Wagner /
Daniil Frumin /
Deepak Jois /
Denys Duchier /
Dominic Steinitz /
Doug Beardsley /
Felipe Lessa /
Florent Becker /
Gabor Greif /
Hans Höglund /
Heinrich Apfelmus /
Ian Ross /
Jan Bracker /
Jeffrey Rosenbluth /
Jeremy Gibbons /
Jeroen Bransen /
Jim Snavely /
Joachim Breitner /
Joel Burget /
John Lato /
John Tromp /
Jonas Haag /
Kanchalai Suveepattananont /
Kaspar Emanuel /
Konrad Madej /
Konstantin Zudov /
Luite Stegeman /
Michael Sloan /
Michael Thompson /
Moiman /
Niklas Haas /
Peter Hall /
Pontus Granström /
Robbie Gleichman /
Robert Vollmert /
Ryan Scott /
Ryan Yates /
Sam Griffin /
Scott Walck /
Sergei Trofimovich /
sleepyMonad /
soapie /
Steve Sprang /
Steven Smith /
Tad Doxsee /
Taneb /
Taru Karttunen /
Tillmann Vogt /
Tim Docker /
Vilhelm Sjöberg /
Vincent Berthoux /
Yiding Jia</p></div></div></div></div>

</div>]]></description>
    <pubDate>Sat, 25 Apr 2015 00:00:00 UT</pubDate>
    <guid>http://projects.haskell.org/diagrams/blog/2015-04-24-diagrams-1.3.html</guid>
    <dc:creator>diagrams contributors</dc:creator>
</item>
<item>
    <title>Introduction to Palette, Part 2</title>
    <link>http://projects.haskell.org/diagrams/blog/2013-12-03-Palette2.html</link>
    <description><![CDATA[<div class="blog-header">
    <p>by <em>Jeffrey Rosenbluth</em> on <strong>December  4, 2013</strong></p>
    <p>Tagged as: <a href="http://projects.haskell.org/diagrams/tags/color.html">color</a>, <a href="http://projects.haskell.org/diagrams/tags/palette.html">palette</a>, <a href="http://projects.haskell.org/diagrams/tags/harmony.html">harmony</a>.</p>
</div>

<div>
    <?xml version="1.0" encoding="UTF-8" ?>
<div class="container bs-docs-container"><div class="row"><div class="col-md-3"><div class="bs-sidebar hidden-print" role="complementary" data-spy="affix"></div></div><div class="col-md-9"><h1 class="title">Introducing the Palette Package, Part II</h1><p>In part 1 of this post we talked mostly about borrowing a set of colors that was made by someone else. In this part we talk about tools we can use to make our own color schemes.</p><p>Most software provides some type of color picker for selecting a single color. To choose a color we are often given the choice between several different color panels, including a clolor wheel, color sliders, and others. The sliders metaphor works well for choosing a single color, but it doesn't provide us with an intuitive way to choose a color scheme.</p><p>The color wheel is more promising. A color wheel is designed to have pure hues on the perimeter, that means saturation and brightness are set to 100%. If you look at this type of color wheel, that is one based on HSB or HSL, you will notice that the red, green and blue sections are 120 degrees apart. If you look at <a class="reference external" href="https://kuler.adobe.com/create/color-wheel/">Adobe Kuler</a> on the other hand you will see that red and green lie on oposite poles of the wheel. That's a better way to visualize the color wheel since red and green are complimentary colors (They produce black or white when combined in the correct proportions). <a class="reference external" href="http://en.wikipedia.org/wiki/Complementary_colors">Complimentary colors</a></p><p>The point is that when picking colors for a scheme, tradional color harmony defines which colors are chosen by choosing a base color and other colors on the wheel at specific angles apart. The wheel that is used though is one with complimentary colors opposite each other like in Kuler. This is the so called traditional or artist's color wheel. We call it the RYB (red, yellow, blue) wheel since it is based on those three being the primary colors and colors in between as mixtures of those.</p><p>The RYB color wheel and the color schemes we will design below are easy to view using the <code class="sourceCode">wheel</code> function. <code class="sourceCode">wheel</code> takes a list of colors and makes a color wheel out of them by placing the first color in the list at the top of the wheel.</p><div class="examplesrc"><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> wheel cs <span class="fu">=</span> wheel' <span class="fu">#</span> rotate r
<span class="ot">></span>   <span class="kw">where</span>
<span class="ot">></span>     wheel' <span class="fu">=</span> mconcat <span class="fu">$</span> zipWith fc cs (iterateN n (rotate a) w)
<span class="ot">></span>     n <span class="fu">=</span> length cs
<span class="ot">></span>     a <span class="fu">=</span> <span class="dv">1</span> <span class="fu">/</span> (fromIntegral n) <span class="fu">@@</span> turn
<span class="ot">></span>     w <span class="fu">=</span> wedge <span class="dv">1</span> xDir a <span class="fu">#</span> lwG <span class="dv">0</span>
<span class="ot">></span>     r <span class="fu">=</span> (<span class="dv">1</span><span class="fu">/</span><span class="dv">4</span> <span class="fu">@@</span> turn)  <span class="fu">^-^</span>  (<span class="dv">1</span><span class="fu">/</span>(<span class="dv">2</span><span class="fu">*</span>(fromIntegral n)) <span class="fu">@@</span> turn)</code></pre></div></div><p>Here is the RYB color wheel. Notice that colors we perceive as opposites, e.g. red and green are 180 degrees apart on the wheel. In <code class="sourceCode">harmony</code> the RYB color wheel is created by shrinking and stretching sections of the HSB color wheel so that complimentary colors are always on opposite sides of the wheel.</p><div class="examplesrc"><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> ryb <span class="fu">=</span> [rybColor n <span class="fu">|</span> n <span class="ot"><-</span> [<span class="dv">0</span><span class="fu">..</span><span class="dv">23</span>]]
<span class="ot">></span> example <span class="fu">=</span> wheel ryb</code></pre></div></div><div class="exampleimg"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/4d18e35a23b01f5e.png" width="500" height="200" /></div></div><p>Although we have described the base color as a pure hue, we are actually free to choose any color we like at the base color. In order to create the harmonies we desire, we want a function that takes a given color and returns the color a certain number of degrees away on the RYB wheel. For that <code class="sourceCode">harmony</code> provides the function <code class="sourceCode">rotateColor</code>. Here is the original d3 color set and the same set rotated by 60 degrees (counter clockwise).</p><div class="examplesrc"><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> d3 <span class="fu">=</span> [d3Colors1 n <span class="fu">|</span> n <span class="ot"><-</span> [<span class="dv">0</span><span class="fu">..</span><span class="dv">9</span>]]
<span class="ot">></span> example <span class="fu">=</span> hcat' (with <span class="fu">&</span> sep <span class="fu">.~</span> <span class="fl">0.5</span>) [bar d3, bar <span class="fu">$</span> map (rotateColor <span class="dv">60</span>) d3]</code></pre></div></div><div class="exampleimg"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/b690740a02d680c9.png" width="500" height="200" /></div></div><p>Let's pick a base color to demonstrate the classic color harmonies and how to use the <code class="sourceCode"><span class="dt">Harmony</span></code> functions. How about a nice mustardy yellow "#FFC200".</p><div class="exampleimg"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/b234d37e82e9c06c.png" width="500" height="200" /></div></div><p>Since we have been talking about complimentary colors, the first scheme we describe is unsurprisingly called <em>Complimentary</em>. It's based on two complimentary colors and in the <code class="sourceCode"><span class="dt">Harmmony</span></code> module three other colors are choosen by shading and tinting those two colors.</p><div class="examplesrc"><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> example <span class="fu">=</span> hcat' (with <span class="fu">&</span> sep <span class="fu">.~</span> <span class="fl">0.5</span>) [ bar (take <span class="dv">2</span> (complement base))
<span class="ot">></span>                                     , wheel <span class="fu">$</span> complement base]</code></pre></div></div><div class="exampleimg"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/288e7a45c341ba7f.png" width="500" height="200" /></div></div><p>A <em>Monochromatic</em> color harmony consists of the base color plus various tints, shades and tones.</p><div class="examplesrc"><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> example <span class="fu">=</span> wheel <span class="fu">$</span> monochrome base</code></pre></div></div><div class="exampleimg"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/c02578d6039e7dda.png" width="500" height="200" /></div></div><p>The following scheme does not have a name as far as I know. We take the base color and mix a little bit of it into black, grey, and white. In <code class="sourceCode"><span class="dt">Harmony</span></code> the function is called <code class="sourceCode">bwg</code>.</p><div class="examplesrc"><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> example <span class="fu">=</span> wheel <span class="fu">$</span> bwg base</code></pre></div></div><div class="exampleimg"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/8163ad3def731872.png" width="500" height="200" /></div></div><p>Sometimes it is useful to view a color scheme like a wheel but with the base color as a disc in the center. We define the function <code class="sourceCode">pie</code> for this purpose.</p><div class="examplesrc"><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> pie (c<span class="fu">:</span>cs) <span class="fu">=</span> ring <span class="fu"><></span> center
<span class="ot">></span>   <span class="kw">where</span>
<span class="ot">></span>     center <span class="fu">=</span> circle <span class="fl">0.5</span> <span class="fu">#</span> fc c <span class="fu">#</span> lwG <span class="dv">0</span>
<span class="ot">></span>     ring <span class="fu">=</span> mconcat <span class="fu">$</span> zipWith fc cs (iterateN n (rotate a) w)
<span class="ot">></span>     n <span class="fu">=</span> length cs
<span class="ot">></span>     a <span class="fu">=</span> <span class="dv">1</span> <span class="fu">/</span> (fromIntegral n) <span class="fu">@@</span> turn
<span class="ot">></span>     w <span class="fu">=</span> annularWedge <span class="fl">0.5</span> <span class="dv">1</span> xDir a <span class="fu">#</span> lwG <span class="dv">0</span></code></pre></div></div><p>The <em>Analogic</em> color scheme is the base color plus the two colors 30 degrees apart on each side. As usual we add in some tints, shades, and tones to fill out a 5 color scheme. <em>Accent Analogic</em> is similar but we add in the color complimentary to the base color.</p><div class="examplesrc"><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> example <span class="fu">=</span> hcat' (with <span class="fu">&</span> sep <span class="fu">.~</span> <span class="fl">0.5</span>) [ pie <span class="fu">$</span> analogic base
<span class="ot">></span>                                     , pie <span class="fu">$</span> accentAnalogic base]</code></pre></div></div><div class="exampleimg"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/b27057951cfbd3bc.png" width="500" height="200" /></div></div><p>The lase two schemes provided by <code class="sourceCode"><span class="dt">Harmony</span></code> are <em>Triad</em>, with colors 120 degrees apart and <em>Tetrad</em> with colors on the corners of a rectangle inscribed in the color wheel.</p><div class="examplesrc"><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> example <span class="fu">=</span> hcat' (with <span class="fu">&</span> sep <span class="fu">.~</span> <span class="fl">0.5</span>) [ pie <span class="fu">$</span> triad base
<span class="ot">></span>                                     , pie <span class="fu">$</span> tetrad base]</code></pre></div></div><div class="exampleimg"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/e7827a64966ad72d.png" width="500" height="200" /></div></div></div></div></div>

</div>]]></description>
    <pubDate>Wed, 04 Dec 2013 00:00:00 UT</pubDate>
    <guid>http://projects.haskell.org/diagrams/blog/2013-12-03-Palette2.html</guid>
    <dc:creator>diagrams contributors</dc:creator>
</item>
<item>
    <title>Introduction to Palette, Part 1</title>
    <link>http://projects.haskell.org/diagrams/blog/2013-12-03-Palette1.html</link>
    <description><![CDATA[<div class="blog-header">
    <p>by <em>Jeffrey Rosenbluth</em> on <strong>December  3, 2013</strong></p>
    <p>Tagged as: <a href="http://projects.haskell.org/diagrams/tags/color.html">color</a>, <a href="http://projects.haskell.org/diagrams/tags/palette.html">palette</a>, <a href="http://projects.haskell.org/diagrams/tags/brewer.html">brewer</a>, <a href="http://projects.haskell.org/diagrams/tags/d3.html">d3</a>.</p>
</div>

<div>
    <?xml version="1.0" encoding="UTF-8" ?>
<div class="container bs-docs-container"><div class="row"><div class="col-md-3"><div class="bs-sidebar hidden-print" role="complementary" data-spy="affix"></div></div><div class="col-md-9"><h1 class="title">Introducing the Palette Package, Part I</h1><subtitle ids="introduction" names="introduction">Introduction</subtitle><p>Choosing a set of colors that look good together can be quite a challenge. The task comes up in a variety of different contexts including: webiste design, print design, cartography, and as we will discuss here, making diagrams. The problem comes down to a balancing act between two issues; first is that the choosen set of colors is asthetically pleasing, and second is that there is enough contrast between them.</p><p>The easiest approach is to borrow a set of colors from someone who has already put in the time and effort to create it. The Palette package "Data.Colour.Palette.ColorSet" provides access to a few different predefined color sets including <a class="reference external" href="https://github.com/mbostock/d3/wiki/Ordinal-Scales">the ones in d3</a> and the package "Data.Colour.Palette.BrewerSet" contains a large variety of color schemes created by Cynthia Brewer for use in map making see <a class="reference external" href="http://colorbrewer2.org/">colorbrewer 2.0</a>.</p><p>Let's start out by building some tools in Diagrams, the Haskell drawing framework. We will use the golden ration to give us some pleasing proportions.</p><div class="examplesrc"><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> gr <span class="fu">=</span> (<span class="dv">1</span> <span class="fu">+</span> sqrt <span class="dv">5</span>) <span class="fu">/</span> <span class="dv">2</span></code></pre></div></div><p>The function <code class="sourceCode">bar</code> takes a list of colors which we define here as <code class="sourceCode">[<span class="dt">Colour</span> <span class="dt">Double</span>]</code> (we often use the type synonym <code class="sourceCode">[<span class="dt">Kolor</span>]</code>). We set the length of the color bar to the golden ratio and the height to 1.</p><div class="examplesrc"><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> bar cs <span class="fu">=</span> hcat [square gr <span class="fu">#</span> scaleX s <span class="fu">#</span> fc k <span class="fu">#</span> lwG <span class="dv">0</span> <span class="fu">|</span> k <span class="ot"><-</span> cs] <span class="fu">#</span> centerXY
<span class="ot">></span>   <span class="kw">where</span> s <span class="fu">=</span> gr <span class="fu">/</span> (fromIntegral (length cs))</code></pre></div></div><p>We can use <code class="sourceCode">bar</code> to view the color sets in <code class="sourceCode"><span class="dt">Palette</span></code>. Let's make a few color bars. We will use functions provided in <code class="sourceCode"><span class="dt">Palette</span></code> to make the color lists and then use <code class="sourceCode">bar</code> to make the diagrams. The function <code class="sourceCode">d3Colors1</code> takes an <code class="sourceCode"><span class="dt">Int</span></code> between 0 and 9 and returns a color from the set.</p><div class="examplesrc"><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> d3 <span class="fu">=</span> [d3Colors1 n <span class="fu">|</span> n <span class="ot"><-</span> [<span class="dv">0</span><span class="fu">..</span><span class="dv">9</span>]]
<span class="ot">></span> example <span class="fu">=</span> bar d3</code></pre></div></div><div class="exampleimg"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/a7fbf9bf3aaad2a8.png" width="500" height="200" /></div></div><p>The function we use to access schemes from <code class="sourceCode"><span class="dt">Data.Colour.Palette.Brewerset</span></code> is <code class="sourceCode">brewerSet</code>. It takes two arguments: the category of the set <code class="sourceCode"><span class="dt">ColorCat</span></code> (see the haddocks documentation for a list of categories), and an integer representing how many colors in the set. The sets are divided up into 3 categories primarily for showing different types of data on a map: sequential, diverging and qualitative. But they are useful for making diagrams as well.</p><div class="examplesrc"><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> gb <span class="fu">=</span> bar <span class="fu">$</span> brewerSet <span class="dt">GnBu</span> <span class="dv">9</span>    <span class="co">-- green/blue, sequential multihue</span>
<span class="ot">></span> po <span class="fu">=</span> bar <span class="fu">$</span> brewerSet <span class="dt">PuOr</span> <span class="dv">11</span>   <span class="co">-- purple/orange, diverging</span>
<span class="ot">></span> bs <span class="fu">=</span> bar <span class="fu">$</span> brewerSet <span class="dt">Paired</span> <span class="dv">11</span> <span class="co">-- qualitative</span>
<span class="ot">></span> example <span class="fu">=</span> hcat' (with <span class="fu">&</span> sep <span class="fu">.~</span> <span class="fl">0.5</span>) [gb, po, bs]</code></pre></div></div><div class="exampleimg"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/4e375f484cb7e16f.png" width="500" height="200" /></div></div><p>Some of the color sets provided in <code class="sourceCode"><span class="dt">ColorSet</span></code> occur with 2 or 4 brightness levels. <code class="sourceCode"><span class="kw">data</span> <span class="dt">Brightness</span> <span class="fu">=</span> <span class="dt">Darkest</span> <span class="fu">|</span> <span class="dt">Dark</span> <span class="fu">|</span> <span class="dt">Light</span> <span class="fu">|</span> <span class="dt">Lightest</span></code> with <code class="sourceCode"><span class="dt">Darkest</span> <span class="fu">==</span> <span class="dt">Dark</span></code> and similarly for <code class="sourceCode"><span class="dt">Light</span></code> when using a two set variant. The <code class="sourceCode">grid</code> function is useful for visualizing these.</p><p><code class="sourceCode">grid</code> takes a nested list of colors <code class="sourceCode">[[<span class="dt">Kolor</span>]]</code> and returns a grid of vertically stacked bars.</p><div class="examplesrc"><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> grid cs <span class="fu">=</span> centerXY <span class="fu">$</span> vcat [bar c <span class="fu">#</span> scaleY s <span class="fu">|</span> c <span class="ot"><-</span> cs]
<span class="ot">></span>   <span class="kw">where</span> s <span class="fu">=</span> <span class="dv">1</span> <span class="fu">/</span> (fromIntegral (length cs))
<span class="ot">></span>
<span class="ot">></span> d3Pairs <span class="fu">=</span> [[d3Colors2  <span class="dt">Dark</span>  n <span class="fu">|</span> n <span class="ot"><-</span> [<span class="dv">0</span><span class="fu">..</span><span class="dv">9</span>]], [d3Colors2 <span class="dt">Light</span> n <span class="fu">|</span> n <span class="ot"><-</span> [<span class="dv">0</span><span class="fu">..</span><span class="dv">9</span>]]]
<span class="ot">></span> g2 <span class="fu">=</span> grid d3Pairs
<span class="ot">></span>
<span class="ot">></span> d3Quads <span class="fu">=</span> [[d3Colors4 b n <span class="fu">|</span> n <span class="ot"><-</span> [<span class="dv">0</span><span class="fu">..</span><span class="dv">9</span>]] <span class="fu">|</span> b <span class="ot"><-</span> [<span class="dt">Darkest</span>, <span class="dt">Dark</span>, <span class="dt">Light</span>, <span class="dt">Lightest</span>]]
<span class="ot">></span> g4 <span class="fu">=</span> grid d3Quads
<span class="ot">></span> example <span class="fu">=</span> hcat' (with <span class="fu">&</span> sep <span class="fu">.~</span> <span class="fl">0.5</span>) [g2, g4]</code></pre></div></div><div class="exampleimg"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/394a64915f14d3f1.png" width="500" height="200" /></div></div><p>The are over 300 colors that W3C recommends that every browser support. These are usually list in alphabetical order, which needless to say does not separate similar colors well.  <code class="sourceCode"><span class="dt">Palette</span></code> provides the function <code class="sourceCode">webColors</code> which takes an integer <em>n</em> returns the <em>n</em> th color in a list which has first been sorted by hue and then travesed by skiping every 61 elements. This cycles through a good amount of colors before repeating similar hues. The variant <code class="sourceCode">infiniteWebColors</code> recycles this list. When using these colors it's a good idea to pick some random starting point and increment the color number by 1 every time a new color is required.</p><div class="examplesrc"><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> web <span class="fu">=</span> [[webColors (<span class="dv">19</span> <span class="fu">*</span> j <span class="fu">+</span> i) <span class="fu">|</span> i <span class="ot"><-</span> [<span class="dv">0</span><span class="fu">..</span><span class="dv">8</span>]] <span class="fu">|</span> j <span class="ot"><-</span> [<span class="dv">0</span><span class="fu">..</span><span class="dv">8</span>]]
<span class="ot">></span> w1 <span class="fu">=</span> grid web
<span class="ot">></span>
<span class="ot">></span> web2 <span class="fu">=</span> [[webColors (<span class="dv">19</span> <span class="fu">*</span> j <span class="fu">+</span> i) <span class="fu">|</span> i <span class="ot"><-</span> [<span class="dv">0</span><span class="fu">..</span><span class="dv">19</span>]] <span class="fu">|</span> j <span class="ot"><-</span> [<span class="dv">0</span><span class="fu">..</span><span class="dv">14</span>]]
<span class="ot">></span> w2 <span class="fu">=</span> grid web2
<span class="ot">></span> example <span class="fu">=</span> hcat' (with <span class="fu">&</span> sep <span class="fu">.~</span> <span class="fl">0.5</span>) [w1, w2]</code></pre></div></div><div class="exampleimg"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/1890ba105bcb8e3c.png" width="500" height="200" /></div></div><p>If none of the above color schemes suit your purposes or if you just want to create your own - use the functions in <code class="sourceCode"><span class="dt">Data.Colour.Palette.Harmony</span></code>. The module provides some basic functions for adjusting colors plus a progammatic interface to tools like <a class="reference external" href="https://kuler.adobe.com/create/color-wheel/">Adobe Kuler</a> and <a class="reference external" href="http://colorschemedesigner.com/">Color Scheme Designer</a>. We'll finish Part 1 of this post by examining some of the functions provided to tweak a color: <code class="sourceCode">shade</code>, <code class="sourceCode">tone</code> and <code class="sourceCode">tint</code>. These three functions mix a given color with black, gray, and white repsectively. So if for example we wanted a darker version of the d3 scheme, we can apply a shade.
Or we can add some gray to the brewer set <code class="sourceCode"><span class="dt">GnBu</span></code> from above.</p><div class="examplesrc"><div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span class="ot">></span> s <span class="fu">=</span> bar <span class="fu">$</span> map (shade <span class="fl">0.75</span>) d3
<span class="ot">></span> t <span class="fu">=</span> bar <span class="fu">$</span> map (tone <span class="fl">0.65</span>) (brewerSet <span class="dt">GnBu</span> <span class="dv">9</span>)
<span class="ot">></span> example <span class="fu">=</span> hcat' (with <span class="fu">&</span> sep <span class="fu">.~</span> <span class="fl">0.5</span>) [s, t]</code></pre></div></div><div class="exampleimg"><div style="text-align: center"><img src="http://projects.haskell.org/diagrams/blog/images/bc276864403a1672.png" width="500" height="200" /></div></div><p>In part II we will talk just a bit about color theory and explain more of the fucntions in <code class="sourceCode"><span class="dt">Harmony</span></code>.</p></div></div></div>

</div>]]></description>
    <pubDate>Tue, 03 Dec 2013 00:00:00 UT</pubDate>
    <guid>http://projects.haskell.org/diagrams/blog/2013-12-03-Palette1.html</guid>
    <dc:creator>diagrams contributors</dc:creator>
</item>

    </channel>
</rss>
