<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.3">Jekyll</generator><link href="http://bridgermaxwell.com/feed.xml" rel="self" type="application/atom+xml" /><link href="http://bridgermaxwell.com/" rel="alternate" type="text/html" /><updated>2024-06-21T14:40:46-04:00</updated><id>http://bridgermaxwell.com/feed.xml</id><title type="html">Bridger Maxwell</title><entry><title type="html">Apartment Lights</title><link href="http://bridgermaxwell.com/blog/lights/" rel="alternate" type="text/html" title="Apartment Lights" /><published>2016-12-10T09:00:00-05:00</published><updated>2016-12-10T09:00:00-05:00</updated><id>http://bridgermaxwell.com/blog/lights</id><content type="html" xml:base="http://bridgermaxwell.com/blog/lights/"><![CDATA[<p>A couple years ago I made a DIY gift for my husband. I fitted
our apartments with LEDs, custom animations, and an app to control them.</p>

<h1 id="animations">Animations</h1>

<p>We’ve got some unique animations, coded by me but with direction from Josh</p>

<h2 id="stars">Stars</h2>

<video poster="/assets/clips/Lights/Animation-Stars-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/Lights/Animation-Stars.mov" type="video/mp4" />
</video>

<h2 id="waves">Waves</h2>

<video poster="/assets/clips/Lights/Animation-Waves-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/Lights/Animation-Waves.mov" type="video/mp4" />
</video>

<h2 id="fireworks">Fireworks</h2>

<video poster="/assets/clips/Lights/Animation-Fireworks-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/Lights/Animation-Fireworks.mov" type="video/mp4" />
</video>

<p>Of course, the lights can just be on, or we have a preset that puts them on
a dim orange setting to promote sleepiness.</p>

<h1 id="app">App</h1>

<p>The lights are controlled with an app we’ve codenamed Lite Brite. You can get to
the controls on the lock screen. The left side controls the living room and the
right buttons control the bedroom lights.</p>

<p>[Lock Screen Lights]</p>

<p>Inside the app you can also set an alarm time. When the alarm goes off the lights
in the bedroom slowly turn on and then begin to flash.</p>

<p>[Full App]</p>

<h1 id="components">Components</h1>

<p>The living room has 10 meters of LEDs. They are the <a href="https://www.adafruit.com/product/1138">NeoPixel
LEDs from Adafruit</a>.</p>

<p>The LEDs are controlled by a Raspberry Pi which is running the custom software.
It communicates with a server (written in Go and hosted by Heroku) so we can
change the lights even from outside the apartment. It it fun to change the
lights and try to find our window on the skyline.</p>

<h1 id="extra-fun">Extra Fun</h1>

<p>After a vacation to The Wizarding World of Harry Potter was cancelled, I put
in our own magic. There is a <a href="https://www.amazon.com/HARRY-POTTER-Remote-Control-Wand/dp/B00FXMDRZK">Harry Potter wand</a>
which recognizes gestures and acts just like a TV remote. By adding an infrared
sensor to the Raspberry Pi, it can receive commands from the wand.</p>

<p>[Wizard video]</p>

<p>Josh’s latest request is to endow a gavel with the powers of Mjölnir. We will
see where that goes…</p>]]></content><author><name></name></author><category term="hacks" /><category term="diy" /><category term="electronics" /><summary type="html"><![CDATA[A couple years ago I made a DIY gift for my husband. I fitted our apartments with LEDs, custom animations, and an app to control them.]]></summary></entry><entry><title type="html">NumberPad - Discovering Laws of Math</title><link href="http://bridgermaxwell.com/blog/numberpad-discovery/" rel="alternate" type="text/html" title="NumberPad - Discovering Laws of Math" /><published>2016-09-30T09:00:00-04:00</published><updated>2016-09-30T09:00:00-04:00</updated><id>http://bridgermaxwell.com/blog/numberpad-discovery</id><content type="html" xml:base="http://bridgermaxwell.com/blog/numberpad-discovery/"><![CDATA[<h1 id="discovering-laws-of-math">Discovering Laws of Math</h1>

<p>One amazing part of mathematics is that the laws are universal. You don’t need to be told that for every circle \(\frac{circumference}{diameter} = 3.14159....\), because you can discover it yourself. If we met aliens, we’d expect they’d have discovered these same truths. Kinda crazy!</p>

<p>Doing real math is discovering and proving new relationships. Doing math in a classroom is not like this at all. Could we set up students to discover these laws for themselves?</p>

<p>I’ve created a few puzzles in NumberPad for discovering these universal truths independently. I’m inspired by video games which put you on the right path and give just enough clues, but still have you feeling 💃😁🎉 when you solve it.</p>

<p>(If you haven’t read about NumberPad yet, check out
<a href="/blog/numberpad-notation/">this previous post</a> to see the
basics. This post will be a lot more interesting with that context.)</p>

<p>For this puzzle, pretend you don’t know that you haven’t learned about \(\pi\) yet. Let’s discover it.</p>

<p>We’ve got a circle. You can change the diameter:</p>

<video poster="/assets/clips/NumberPad/Discovery-1-CircleDiameter-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Discovery-1-CircleDiameter.mov" type="video/mp4" />
</video>

<p>You can play with the circumference, and try to make it match up with the circle. When it does match up, it turns dark blue.</p>

<video poster="/assets/clips/NumberPad/Discovery-2-CircleCircumference-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Discovery-2-CircleCircumference.mov" type="video/mp4" />
</video>

<p>The point of this puzzle is to figure out the relationship between those two numbers so that it will work for every circle. NumberPad only supports addition, multiplication, and exponentiation, so let’s just pick one and try it. Maybe the relationship is \({diameter}^{something?} = {circumference}\)</p>

<video poster="/assets/clips/NumberPad/Discovery-3-CircleExponent-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Discovery-3-CircleExponent.mov" type="video/mp4" />
</video>

<p>For this circle, that “something” was \(1.50\). Does that work for other circles? Have we discovered a law of the mathematical universe? We can change the diameter and see the circumference change.</p>

<video poster="/assets/clips/NumberPad/Discovery-4-CircleExponentScrub-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Discovery-4-CircleExponentScrub.mov" type="video/mp4" />
</video>

<p>Hmm, nope. The circumference changed with the diameter but the new circumference didn’t line up. There is an easier way to see how wrong our guess it. We can show other circles with different diameters and see that our guess overshoots the circumference on the big circles and undershoots the diameter on small circles.</p>

<video poster="/assets/clips/NumberPad/Discovery-5-CircleExponentGhosts-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Discovery-5-CircleExponentGhosts.mov" type="video/mp4" />
</video>

<p>Making mistakes is okay. Let’s try anotehr simple relationship. Maybe (just maybe), it is \({diameter} * {something?} = {circumference}\).</p>

<video poster="/assets/clips/NumberPad/Discovery-6-CircleMultiply-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Discovery-6-CircleMultiply.mov" type="video/mp4" />
</video>

<p>For those of you in the know, the \(3.14\) is pretty promising. Let’s try it on other circle sizes.</p>

<video poster="/assets/clips/NumberPad/Discovery-7-CircleMultiplyScrub-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Discovery-7-CircleMultiplyScrub.mov" type="video/mp4" />
</video>

<p>What do you know?! It works on those other circles too! Maybe this relationship is universal? How weird that it depends on such a specific number like \(3.14\)… I wonder if that number ever comes up in other places? 😉</p>

<p>What is more fun than a circle? How about a square!?! 😮 This next puzzle is leading up to a pretty great one, so it is worth it.</p>

<p>With this square we can control the side length:</p>

<video poster="/assets/clips/NumberPad/Discovery-8-SquareSide-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Discovery-8-SquareSide.mov" type="video/mp4" />
</video>

<p>And we want to figure out the area of the square. For this one, we can tell it is \(81\) because everything lines up and turns a nice color.</p>

<video poster="/assets/clips/NumberPad/Discovery-9-SquareArea-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Discovery-9-SquareArea.mov" type="video/mp4" />
</video>

<p>We’ve got to find a relationship that ties those numbers together, but works for all squares. An enterprising (but, as we know, wrong) student might think the relationship is \(length * something = area\). Let’s see how that plays out.</p>

<video poster="/assets/clips/NumberPad/Discovery-10-SquareMultiplying-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Discovery-10-SquareMultiplying.mov" type="video/mp4" />
</video>

<p>Hrmmm. The area starts out too big on the small squares and doesn’t grow fast enough for the big squares. Let’s try a relationship that grows faster. EXPONENTIATION!</p>

<video poster="/assets/clips/NumberPad/Discovery-11-SquareExponent-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Discovery-11-SquareExponent.mov" type="video/mp4" />
</video>

<p>Sweet! It works for all the squares we care to test. We’ve discovered another law of the universe! 🏆</p>

<p>That set’s us up for the best puzzle I’ve programmed so far……</p>

<p><em>THE PYTHAGOREAM THEOREM!!!!!</em> 😲</p>

<p>In this puzzle we can change the length of the blue line or the green line, and we are trying to figure out how big the orange line should be. We want that orange square to be all dark colored.</p>

<video poster="/assets/clips/NumberPad/Discovery-12-PythagoreanScrubbing-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Discovery-12-PythagoreanScrubbing.mov" type="video/mp4" />
</video>

<p>This puzzle could probably use some stars and sparkles when you get the right answer. 🤔 Open source contribution, anyone?</p>

<p>For this puzzle, randomly guessing relationships won’t be very successful. First, let’s do a part that we know. Those blue, green, and orange squares?</p>

<p><img src="/assets/images/numberpad-pythagorean-squared.png" alt="pythagorean diagram with squares" /></p>

<p>From the last puzzle we know how to make a square’s area. Let’s do that for each one.</p>

<video poster="/assets/clips/NumberPad/Discovery-13-PythagoreanSquaring-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Discovery-13-PythagoreanSquaring.mov" type="video/mp4" />
</video>

<p>Maybe this is progress, but what is the relationship between those squared numbers? For this part we’ll need a clever breakthrough, which we can get by studying the shapes.</p>

<p>There are two large squares of the same size. Each of those large squares has 4 triangles in it. Each triangle is the same size because they each have a blue, green, and orange side.</p>

<p><img src="/assets/images/numberpad-pythagorean-triangles.png" alt="pythagorean diagram with squares" /></p>

<p>So, if we take away the four triangles, what is left? On one side we have the blue and green squares. One the other side we have the orange square.</p>

<p><img src="/assets/images/numberpad-pythagorean-cutout.png" alt="pythagorean diagram with squares" /></p>

<p>The blue and green square must be the same size as the orange! We try adding them together…..</p>

<video poster="/assets/clips/NumberPad/Discovery-14-PythagoreanAdd-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Discovery-14-PythagoreanAdd.mov" type="video/mp4" />
</video>

<p>And voila! We’ve figured out the relationship between green, blue, and orange (or \(a\), \(b\), and \(c\), if you prefer). We can change the green number and our newfound relationship, \(a^2 + b^2 = c^2\) finds the new orange number.</p>

<video poster="/assets/clips/NumberPad/Discovery-15-PythagoreanCheckA-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Discovery-15-PythagoreanCheckA.mov" type="video/mp4" />
</video>

<p>We can even change the orange number and solve for the new blue number.</p>

<video poster="/assets/clips/NumberPad/Discovery-16-PythagoreanSolveB-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Discovery-16-PythagoreanSolveB.mov" type="video/mp4" />
</video>

<p>These puzzles show just the beginning of what could be done in Numberpad. Imagine trying to do these same puzzles with pencil and paper worksheets. In the words of Donald Trump, <em>it would be a disaster</em>.</p>

<p>The machanics of algebra on paper make it difficult to discover something new. It is more likely that a student would make an error like \({(a + b = c)}^2\). Worse, that student wouldn’t even know that was a mistake until the worksheet came back graded a few days later.</p>

<p>In Numberpad, a student has the freedom to play with math knowing they won’t accidentally “break the rules”.</p>

<div class="breaker"></div>

<p>If you think NumberPad could be used in a classroom, please reach out. I’d love
to turn these prototypes into a curriculum. Email me at <a href="mailto:bridger.maxwell@gmail.com">bridger.maxwell@gmail.com</a>
or find me on Twitter as <a href="https://twitter.com/bridgermax">@bridgermax</a>.</p>

<!--  -->]]></content><author><name></name></author><category term="playground" /><category term="open source" /><category term="math" /><category term="education" /><category term="NumberPad" /><summary type="html"><![CDATA[Discovering Laws of Math]]></summary></entry><entry><title type="html">NumberPad - Playing with Numbers</title><link href="http://bridgermaxwell.com/blog/numberpad-toys/" rel="alternate" type="text/html" title="NumberPad - Playing with Numbers" /><published>2016-06-15T09:00:00-04:00</published><updated>2016-06-15T09:00:00-04:00</updated><id>http://bridgermaxwell.com/blog/numberpad-toys</id><content type="html" xml:base="http://bridgermaxwell.com/blog/numberpad-toys/"><![CDATA[<h1 id="toys-in-numberpad">Toys in NumberPad</h1>

<p>Numbers can represent almost anything — <a href="http://what-if.xkcd.com/144/">saliva production per day</a>,
<a href="http://what-if.xkcd.com/124/">the cost of a pool on the moon</a>, or
<a href="http://what-if.xkcd.com/80/">the volume of earth’s viruses</a>. Yet, on their own
they are kinda boring.</p>

\[487\]

<p>NumberPad is for playing with numbers. (Check out
<a href="/blog/numberpad-notation/">this previous post</a> to see the
basics of NumberPad.) How can we show numbers in a less boring way? Here is one
small experiment of tying those numbers to “toys”.</p>

<p>This football is tied to <code class="language-plaintext highlighter-rouge">x</code> and <code class="language-plaintext highlighter-rouge">y</code>. When those numbers change, the
football moves to match.</p>

<video poster="/assets/clips/NumberPad/Toys-1-Toy-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Toys-1-Toy.mov" type="video/mp4" />
</video>

<p>We can make <code class="language-plaintext highlighter-rouge">x</code> and <code class="language-plaintext highlighter-rouge">y</code> both depend on <code class="language-plaintext highlighter-rouge">time</code>, then make the football move both
directions at once. I set up the equations \(x = velocity_x * time\) and
\(y = time^{power}\). With <code class="language-plaintext highlighter-rouge">time</code> selected, I can change the value and have
it update both <code class="language-plaintext highlighter-rouge">x</code> and <code class="language-plaintext highlighter-rouge">y</code>.</p>

<video poster="/assets/clips/NumberPad/Toys-2-Time-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Toys-2-Time.mov" type="video/mp4" />
</video>

<p>If we wanted to tweak <code class="language-plaintext highlighter-rouge">power</code> and see how it changes the arc we could:</p>

<ol>
  <li>Select <code class="language-plaintext highlighter-rouge">power</code>.</li>
  <li>Change it from \(y = time^2\) to \(y = time^{2.5}\)</li>
  <li>Select <code class="language-plaintext highlighter-rouge">time</code></li>
  <li>Scrub back and forth to see the new effect</li>
</ol>

<p>The turnaround makes it hard to see the effects of playing with a number. A
better way is to see the entire trajectory of the football all at once, so we
can instantly see the impact of a change. Here is a visualization of the
football trajectory as I change <code class="language-plaintext highlighter-rouge">power</code>.</p>

<video poster="/assets/clips/NumberPad/Toys-3-ExponentGhost-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Toys-3-ExponentGhost.mov" type="video/mp4" />
</video>

<p>What you are seeing are “ghost” versions of the football at <code class="language-plaintext highlighter-rouge">time + 1</code>,
<code class="language-plaintext highlighter-rouge">time + 2</code>, <code class="language-plaintext highlighter-rouge">time + 3</code>, etc as well as <code class="language-plaintext highlighter-rouge">time - 1</code>, <code class="language-plaintext highlighter-rouge">time - 2</code>, <code class="language-plaintext highlighter-rouge">time - 3</code>, etc.</p>

<p><img src="/assets/images/numberpad-ghosts.png" alt="Ghosts with time labels" /></p>

<p>The strength of NumberPad is that you can change any value without solving to
isolate the variable. In this example, that means we can grab the football
and have it change <code class="language-plaintext highlighter-rouge">velocity_x</code> and <code class="language-plaintext highlighter-rouge">power</code> automatically. As I drag the
football and change <code class="language-plaintext highlighter-rouge">x</code> and <code class="language-plaintext highlighter-rouge">y</code>, NumberPad calculates
\(velocity_x = \frac{x}{time}\) and \(power = log_{time}y\).</p>

<video poster="/assets/clips/NumberPad/Toys-4-DirectManipulation-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Toys-4-DirectManipulation.mov" type="video/mp4" />
</video>

<p>NumberPad tries to make equations concrete by always showing one solution to the
equation because most equations are easier with one solid example. Sometimes
a single example is not enough. The most important aspect of an equation might
be how it <em>changes</em>. Showing the trajectory of the football is <a href="http://worrydream.com/LadderOfAbstraction/">higher up the
ladder of abstraction</a>. From this
vantage point we can see how our equation is about motion. We can also see how
the motion itself changes with different values.</p>

<p>We can also use this abstraction to jump to different concrete solutions. Tap
on one of the ghost footballs to jump to a specific time. Here I tap to jump
to the concrete solutions where <code class="language-plaintext highlighter-rouge">time</code> is <code class="language-plaintext highlighter-rouge">2</code>, <code class="language-plaintext highlighter-rouge">5</code>, <code class="language-plaintext highlighter-rouge">6</code>, <code class="language-plaintext highlighter-rouge">7</code>, <code class="language-plaintext highlighter-rouge">9</code>, or <code class="language-plaintext highlighter-rouge">11</code>.</p>

<video poster="/assets/clips/NumberPad/Toys-5-JumpGhosts-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Toys-5-JumpGhosts.mov" type="video/mp4" />
</video>

<p>Putting this all together, we can play with the equation for projectile motion
with gravity. We don’t have to change <code class="language-plaintext highlighter-rouge">x</code>, but the equation for <code class="language-plaintext highlighter-rouge">y</code> is now
\(time * velocity_y + time^2 * gravity\). It looks more complicated in
NumberPad because it shows step of the calculation.</p>

<video poster="/assets/clips/NumberPad/Toys-6-SetupGravity-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Toys-6-SetupGravity.mov" type="video/mp4" />
</video>

<p>Once the equation is set up, I can select <code class="language-plaintext highlighter-rouge">time</code> and scrub it to see the
football fly through the air.</p>

<video poster="/assets/clips/NumberPad/Toys-7-DemoGravity-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Toys-7-DemoGravity.mov" type="video/mp4" />
</video>

<p>It is fun to play around with. I can grab the football have gravity change until
we have the perfect arc.</p>

<video poster="/assets/clips/NumberPad/Toys-8-ChangeGravity-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Toys-8-ChangeGravity.mov" type="video/mp4" />
</video>

<p>Or, we change only the \(velocity_x\) and see that the ghost football stays in
the air for the same amount of time. We can tell because it is always the same
ghost football, which represents the football at \(time = 8.7\) which is
touching the ground.</p>

<video poster="/assets/clips/NumberPad/Toys-9-YZeroTime-frame.jpg" class="inline wide" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Toys-9-YZeroTime.mov" type="video/mp4" />
</video>

<p>Toying with numbers is a fun way to discover relationships and get a feel for
equations. Tying the numbers to a physical representation lets us visualize
them in a concrete way, and the “ghost” effect lets us see the relationships at
a higher level of abstraction.</p>

<div class="breaker"></div>

<p>I’m still at the stage where I’m prototyping these concepts in NumberPad. If
you’ve got ideas for practical applications I’d love to hear them
<a href="https://twitter.com/bridgermax">@bridgermax</a>.</p>

<p><a href="/blog/numberpad-discovery/">Read Part 3: Discovering Laws of Math</a></p>

<!-- 
Outline

How do we represent the values and variables in an equation?

Equations emcompass many different states. When you are familiar with math you
see an equation and think, "when this gets small, this gets big. When this is
big this part doesn't matter. When this is zero it simplifies to that." It is
many simultaneous things.

An equation is both concrete values and the way that it changes over its
inputs.

One tool for seeing both concrete examples and change is graphs. Many concrete
values but also the shape of the curve as it changes.

What other ways can we see

NumberPad always shows one concrete solution to an equation.

 -->]]></content><author><name></name></author><category term="playground" /><category term="open source" /><category term="math" /><category term="education" /><category term="NumberPad" /><summary type="html"><![CDATA[Toys in NumberPad]]></summary></entry><entry><title type="html">NumberPad - Math Notation for iPad</title><link href="http://bridgermaxwell.com/blog/numberpad-notation/" rel="alternate" type="text/html" title="NumberPad - Math Notation for iPad" /><published>2016-05-31T08:00:00-04:00</published><updated>2016-05-31T08:00:00-04:00</updated><id>http://bridgermaxwell.com/blog/numberpad-notation</id><content type="html" xml:base="http://bridgermaxwell.com/blog/numberpad-notation/"><![CDATA[<h1 id="a-new-notation">A new notation</h1>

<p>A few years ago, when I was reading <a href="http://www.amazon.com/Journey-through-Genius-Theorems-Mathematics/dp/014014739X">Journey Through Genius</a>,
I encountered equations from <a href="https://en.wikipedia.org/wiki/Euclid%27s_Elements">Euclid’s
Elements</a> written as
sentences.</p>

<blockquote>
  <p>Any cone is a third part of the cylinder which has the same base with it and
equal height.</p>
</blockquote>

<p><img src="/assets/images/cylinder-and-cone.png" alt="cylinder and cone" /></p>

<p>Today, we would write that relationship as \(volume_{cone} = \frac{1}{3} volume_{cylinder} = \frac{1}{3} \pi r^2 h\),
but that notation wasn’t invented yet! That notation wasn’t even a notion. I hadn’t considered how math was done before
algebraic notation was invented. It seems like \(2 + 2 = 4\) has always existed.</p>

<p>Algebraic notation is much easier to write than the notation Euclid used. We have
some algorithms for manipulating the equations line by line (for example, performing the same operation to
both sides of an equation in order to simplify it). This means human errors
are less common, well, at least in mathematics.</p>

<p>Today, computers perform these rote algebra algorithms more quickly than we can.
It is way easier than streaming and decoding cat videos, which is their primary purpose. We
don’t have to worry about them making careless mistakes, either (user error notwithstanding). What if we
invented a new notation that took the speed and accuracy of computers for granted?
<a href="https://github.com/bridger/NumberPad">NumberPad</a> is an exploration of a new
notation that is built for the strengths of an iPad rather than pencil and
paper.</p>

<h2 id="taxi-fares">Taxi fares</h2>

<p>Let’s jump straight into a demo by calculating some taxi fares. Let’s assume that
a taxi charges a rate of <code class="language-plaintext highlighter-rouge">$3</code> per mile and an initial fare of <code class="language-plaintext highlighter-rouge">$2</code>.
This is \(rate * miles + initialFare = total\). How much would it
cost to travel 5 miles?</p>

<p>First, let’s multiply the <code class="language-plaintext highlighter-rouge">$3</code> rate by <code class="language-plaintext highlighter-rouge">5</code> miles. The green square is a multiplier block. The two inputs
will always multiply to equal the output.</p>

<video poster="/assets/clips/NumberPad/Taxi-1-RateXMiles-frame.jpg" class="inline" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Taxi-1-RateXMiles.mov" type="video/mp4" />
</video>

<p>This comes out to <code class="language-plaintext highlighter-rouge">$15</code>. We add that to the initial fare of
<code class="language-plaintext highlighter-rouge">$2</code> to get the total. The blue circle is the adder block. The two inputs, <code class="language-plaintext highlighter-rouge">15</code> and <code class="language-plaintext highlighter-rouge">2</code>, always add up
to equal the output, <code class="language-plaintext highlighter-rouge">17</code>. A future update may contain the complex calculus and differential equation packages necessary to calculate adjustments for smell of the cab and the bad radio station choice factor.</p>

<video poster="/assets/clips/NumberPad/Taxi-2-RatePlusInitial-frame.jpg" class="inline" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Taxi-2-RatePlusInitial.mov" type="video/mp4" />
</video>

<p>We can add names to the variables to remember what they are.</p>

<video poster="/assets/clips/NumberPad/Taxi-3-RateNames-frame.jpg" class="inline" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Taxi-3-RateNames.mov" type="video/mp4" />
</video>
<p><br /></p>

<p>So far, this is just a handwriting-based calculator. Pretty cool, but
<a href="https://itunes.apple.com/us/app/myscript-calculator-handwriting/id578979413">MyScript Calculator</a>
already does this with algebraic notation. What is the advantage here?</p>

<p>First, we can easily try different values and see how the changes flow through the
equation. What if we traveled 7 miles? We can tap on <code class="language-plaintext highlighter-rouge">miles</code> and change
the value to <code class="language-plaintext highlighter-rouge">7</code>. The <code class="language-plaintext highlighter-rouge">total</code> value updates automatically.</p>

<video poster="/assets/clips/NumberPad/Taxi-4-RateChangeMiles-frame.jpg" class="inline" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Taxi-4-RateChangeMiles.mov" type="video/mp4" />
</video>

<p>We can tell which values will change by looking at the dotted lines between the
values and the blocks.</p>

<p>Or, what if the per-mile rate was $3.40? We tap on <code class="language-plaintext highlighter-rouge">$/mile</code> to select it, then drag the
number at the bottom to change its value.</p>

<video poster="/assets/clips/NumberPad/Taxi-5-ChangeRate-frame.jpg" class="inline" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Taxi-5-ChangeRate.mov" type="video/mp4" />
</video>

<p>The real advantage of NumberPad is that we can change “outputs” and see the
effect on the “inputs”. For example, how many miles can I travel for $30 total?
We tap on <code class="language-plaintext highlighter-rouge">total</code> to select it, then drag to <code class="language-plaintext highlighter-rouge">$30</code> to change its value.</p>

<video poster="/assets/clips/NumberPad/Taxi-6-TotalToMiles-frame.jpg" class="inline" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Taxi-6-TotalToMiles.mov" type="video/mp4" />
</video>

<p>Again, when we drag the number, the values with the dotted
lines are the ones that change.</p>

<p>By tapping on the lines, we can make different lines dotted or solid to control
which amounts stay constant or react to changes. For example, we can also ask
“what was the surge rate if I was charged $40 for 10 miles?” by selecting <code class="language-plaintext highlighter-rouge">total</code> and then
tapping the light green line that connects to <code class="language-plaintext highlighter-rouge">rate</code> so that it is dotted.</p>

<video poster="/assets/clips/NumberPad/Taxi-7-SurgeRate-frame.jpg" class="inline" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Taxi-7-SurgeRate.mov" type="video/mp4" />
</video>

<p>Below each value, we can see the algebraic equations that NumberPad used to
solve these equations:</p>

\[miles = \frac{total - initialFare}{rate}\]

\[rate = \frac{total - initialFare}{miles}\]

<p>However, these equations emphasize the different
<em>operators</em>. It isn’t obvious that they are expressing the same <em>relationship</em>
as the first equation (\(rate * miles + initialFare = total\)).</p>

<h2 id="relationships-and-exponents">Relationships and exponents</h2>

<p>Another example will help show the difference between operations and
relationships. Let’s try \(2^5 = 32\).</p>

<video poster="/assets/clips/NumberPad/Exponent-1-frame.jpg" class="inline" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Exponent-1.mov" type="video/mp4" />
</video>

<p>The orange circle is the exponentiator block. It has a <code class="language-plaintext highlighter-rouge">base</code> of <code class="language-plaintext highlighter-rouge">2</code>, a <code class="language-plaintext highlighter-rouge">power</code> of
<code class="language-plaintext highlighter-rouge">5</code>, and a <code class="language-plaintext highlighter-rouge">total</code> of <code class="language-plaintext highlighter-rouge">32</code>.</p>

<p>Let’s ask “2 raised to the <em>what</em> equals 16?” While <code class="language-plaintext highlighter-rouge">total</code> is selected, we tap
on the dark red line to “dot” it; this causes <code class="language-plaintext highlighter-rouge">power</code> to become the dependent
variable (this also “fixes” <code class="language-plaintext highlighter-rouge">base</code> at <code class="language-plaintext highlighter-rouge">2</code>, as shown by the solid orange line).
Then, we set <code class="language-plaintext highlighter-rouge">total</code> at <code class="language-plaintext highlighter-rouge">16</code>. We see NumberPad calculated the answer as \(\log_2 16 = 4\).</p>

<video poster="/assets/clips/NumberPad/Exponent-2-Log-frame.jpg" class="inline" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Exponent-2-Log.mov" type="video/mp4" />
</video>

<p>I remember logarithms
being difficult to learn. They were scary! Like hearing someone use the bathroom at your house at night, and you live alone scary. Like using the LA interstate when your car is on “E” scary!  Like telling your friends, you thought “Avatar” was just “ok” scary! Exponents were easier, but at the
time I didn’t realize they were the same relationship. Logarithms are just
reverse exponents in the same way that division is reverse multiplication.
NumberPad makes this relationship clear.</p>

<p>We can also change the dependent / “output” variable to <code class="language-plaintext highlighter-rouge">base</code> and
ask, “What other numbers work out nicely with \(x^4 = y\)?” We just tap the
line connected to <code class="language-plaintext highlighter-rouge">base</code> to make it the dependent variable.</p>

<video poster="/assets/clips/NumberPad/Exponent-3-Radical-frame.jpg" class="inline" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Exponent-3-Radical.mov" type="video/mp4" />
</video>

<p>This equation was \(\sqrt[4]{81} = 3\). Another operator for the same
relationship!</p>

<p>The way that algebraic notation is used in schools leads students to believe
that the <code class="language-plaintext highlighter-rouge">=</code> symbol is a prompt for an answer. It is confusing in algebra to see an
equation like \(4 + x = 8y\) which already has an “answer” after the <code class="language-plaintext highlighter-rouge">=</code> sign.
It is a big jump to learn that the <code class="language-plaintext highlighter-rouge">=</code> symbol actually represents a relationship.
The notation in NumberPad tries to make the relationship obvious.</p>

<h1 id="continuously-compounded-interest">Continuously compounded interest</h1>

<p>We will do one more example that is a little more involved. The equation for
continuously compounded interest is \(principal * e^{rate*years} = total\).
Ideally we would be able to write that directly, but in this prototype let’s
write it one piece at a time.</p>

<p>First, a rate of <code class="language-plaintext highlighter-rouge">3%</code> multiplied by <code class="language-plaintext highlighter-rouge">5 years</code>.</p>

<video poster="/assets/clips/NumberPad/Compound-1-RateXYears-frame.jpg" class="inline" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Compound-1-RateXYears.mov" type="video/mp4" />
</video>

<p>Then we take <code class="language-plaintext highlighter-rouge">e</code> and raise it to that result. We can drag from that result to the
dark red node (which is the “power” of the exponentiator) to link it up.</p>

<video poster="/assets/clips/NumberPad/Compound-2-e-frame.jpg" class="inline" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Compound-2-e.mov" type="video/mp4" />
</video>

<p>Now we take our principal investment, <code class="language-plaintext highlighter-rouge">$1000</code> and multiply it by the output from
the exponentiator, <code class="language-plaintext highlighter-rouge">1.16</code>.</p>

<video poster="/assets/clips/NumberPad/Compound-3-PrincipalX-frame.jpg" class="inline" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Compound-3-PrincipalX.mov" type="video/mp4" />
</video>

<p>At <code class="language-plaintext highlighter-rouge">3%</code> interest for <code class="language-plaintext highlighter-rouge">5</code> years, <code class="language-plaintext highlighter-rouge">$1,000</code> will yield <code class="language-plaintext highlighter-rouge">$1,162</code>. Ta da!</p>

<p>What if there were a higher interest rate?</p>

<video poster="/assets/clips/NumberPad/Compound-4-BetterInterest-frame.jpg" class="inline" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Compound-4-BetterInterest.mov" type="video/mp4" />
</video>

<p>We can also answer a more complicated question like, “how many years would it
take to reach <code class="language-plaintext highlighter-rouge">$2,000</code>?” We just select <code class="language-plaintext highlighter-rouge">total</code>, tap the line connected to
<code class="language-plaintext highlighter-rouge">years</code> to make <code class="language-plaintext highlighter-rouge">years</code> the dependent variable, and then set <code class="language-plaintext highlighter-rouge">total</code> to <code class="language-plaintext highlighter-rouge">$2,000</code>.</p>

<video poster="/assets/clips/NumberPad/Compound-5-Goal-frame.jpg" class="inline" autoplay="" loop="" muted="" playsinline="">
    <source src="/assets/clips/NumberPad/Compound-5-Goal.mov" type="video/mp4" />
</video>

<p>Once we write out the equation that sets out the relationship between values,
answering these questions is easy and there is little chance of mistakes.</p>

<h2 id="why">Why?</h2>

<p>Math is a creative and powerful subject. If you find the right
relationship between things, you can predict or control them! You will be the
master of the math magic and turn the lame into toads! Even without a
practical application, finding a truth or noticing a pattern in mathematics can
be beautiful. As with any creative endeavor, you often have to play with ideas
to make them work.</p>

<p>So why is math seen as repetitive and boring? I believe a big reason is that we
spend so much time teaching the algorithms to isolate variables. There are tons
of rules to memorize and if you break one of those rules (like adding to only
one side of an equation, or distributing incorrectly) you don’t find out until
days later when you’ve lost points on your homework or an exam. Computers are
great at rote algorithms, so let them do the boring part!</p>

<p>There is a great essay, <a href="https://www.maa.org/external_archive/devlin/LockhartsLament.pdf">A Mathematician’s
Lament</a> by Paul
Lockhart, which imagines a music class analogous to today’s math education:</p>

<blockquote>
  <p>“Music class is where we take out our staff paper, our teacher puts some
notes on the board, and we copy them or transpose them into a different key.
We have to make sure to get the clefs and key signatures right, and our
teacher is very picky about making sure we fill in our quarter-notes
completely. One time we had a chromatic scale problem and I did it right, but
the teacher gave me no credit because I had the stems pointing the wrong
way.”</p>
</blockquote>

<p>In this world, students don’t get to hear music or strum an instrument until
advanced college classes! I’d like to make an instrument for students to
play with math and see its beauty without years of drills beforehand.</p>

<div class="breaker"></div>

<p>There are other experiments in NumberPad, which I’ll explore in future
posts. <a href="https://github.com/bridger/NumberPad">NumberPad is an open source Swift project</a>,
so you can download it and try it on your iPad. It is only a prototype though,
so it may have trouble with your handwriting or the solver may fail to see a
solution.</p>

<p>Let me know <a href="https://twitter.com/bridgermax">@bridgermax</a> if you enjoyed this
essay or have any ideas for NumberPad. You can also
<a href="https://github.com/bridger/NumberPad/issues/new">open a GitHub issue</a>.</p>

<p><a href="/blog/numberpad-toys/">Read Part 2: Playing with Numbers</a></p>

<p><a href="/blog/numberpad-discovery/">Read Part 3: Discovering Laws of Math</a></p>

<!-- 
Outline

Math is not static. The notation has changed before and shouldn't be taken
    as a given
Math notation today is very well-suited for paper.
Much of manipulating equations is doing rote algorithms.
How can we take advantage of digital tools so the computer is assisting with
    the rote parts of math?
NumberPad is an exploration of a new notation, which highlights
    relationships over operators and applies rote algorithms of solving
    for you.
Example of taxi. Base charge is $2, and $3 per mile traveled. How much will it
    cost to ride 5 miles? (Give names as we go)
It is easy to grab "inputs" and toggle them. How much for 7 miles? What if
    the per-mile charge were increased to $3.40?
The really unique thing is that "inputs" and "outputs" don't really exist. I
    can ask "how far can I go for $20"? It even shows the equations it used to
    figure that variable.
You've seen that you choose the independent / input variable (the one you control with
    the number slider), but how do you choose the dependent / output variable?
    Just tap on the lines to change which direction data flows through the
    relationships.
What if we are Uber, and we want to figure a price?
    ...
This notation is emphasizing the relationship between the numbers, rather than
    the operations on them. To really see the difference, let's look at a
    smaller example.
2^5=32
    Exponents are okay to understand. What if we wanted to ask, "2 raised to the
    what equals 16"? In NumberPad we grab the 32, choose the output to be the
    power and then drag.
We can see that it used log_2 of 16, but I remember that being a difficult
    relationship to learn. Logarithms were scary! Now it is all just exponents.
We can also ask, "what raised to 2 equals 16"? This is the same as square root,
    but when written in normal math notation it isn't at all obvious how it is
    related to exponents.
Let's do one more example, bigger this time. Compounded interest rate.

So, why'd I do this? I believe math is a creative and powerful endeavor. If you
    find the right relationship between things, you can predict or control
    it! You often have the play with the numbers and operations until it works.
    So why is math seen as repetitive and boring? I believe a big reason is
    that we spend so much time teaching the algorithms to isolate variables.
    There are tons of rules to memorize and if you break one of those rules
    (like adding to only one side of an equation, or distributing incorrectly)
    you don't find out until days later when you've lost points on your homework
    or an exam. Computers are great at rote algorithms, so let them do the
    boring part! Let's play with the numbers and get a sense for how they
    behave by directly manipulating them.


For videos use
https://github.com/bfred-it/iphone-inline-video
https://github.com/gka/canvid
 -->]]></content><author><name></name></author><category term="playground" /><category term="open source" /><category term="math" /><category term="education" /><category term="NumberPad" /><summary type="html"><![CDATA[A new notation]]></summary></entry><entry><title type="html">Building on Auto Layout</title><link href="http://bridgermaxwell.com/blog/building-on-auto-layout/" rel="alternate" type="text/html" title="Building on Auto Layout" /><published>2016-05-23T09:30:00-04:00</published><updated>2016-05-23T09:30:00-04:00</updated><id>http://bridgermaxwell.com/blog/building-on-auto-layout</id><content type="html" xml:base="http://bridgermaxwell.com/blog/building-on-auto-layout/"><![CDATA[<p>Auto Layout is the constraint-based layout framework for iOS and OS X. At its core it replaces <code class="language-plaintext highlighter-rouge">setFrame</code> with <code class="language-plaintext highlighter-rouge">addConstraint</code>. Where you would previuosly give the exact coordinates of a view, now you describe the view’s location in relation to other views. It is common to use <code class="language-plaintext highlighter-rouge">addConstraint</code> directly, but Auto Layout is actually a great engine to build layout systems on top of. In this post I’ll talk about different abstraction layers on Auto Layout and show its advantages with my library <a href="https://github.com/bridger/StackLayout">StackLayout</a>.</p>

<p>The simplest way we can build on Auto Layout is a thin syntactic layer for creating constraints that we still manage  manually. Until iOS 9, the built-in way to create a constraint was quite verbose. For example, to make the height of two views equal:</p>

<figure class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="kt">NSLayoutConstraint</span><span class="p">(</span><span class="nv">item</span><span class="p">:</span> <span class="n">redView</span><span class="p">,</span> <span class="nv">attribute</span><span class="p">:</span> <span class="o">.</span><span class="kt">Height</span><span class="p">,</span>
                   <span class="nv">relatedBy</span><span class="p">:</span> <span class="o">.</span><span class="kt">Equal</span><span class="p">,</span>
                   <span class="nv">toItem</span><span class="p">:</span> <span class="n">blueView</span><span class="p">,</span> <span class="nv">attribute</span><span class="p">:</span> <span class="o">.</span><span class="kt">Height</span><span class="p">,</span>
                   <span class="nv">multiplier</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="mi">0</span><span class="p">)</span></code></pre></figure>

<p>The new Layout Anchor API makes this much easier to read:</p>

<figure class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="n">redView</span><span class="o">.</span><span class="n">heightAnchor</span><span class="o">.</span><span class="nf">constraintEqualToAnchor</span><span class="p">(</span><span class="n">blueView</span><span class="o">.</span><span class="n">heightAnchor</span><span class="p">)</span></code></pre></figure>

<p>Other layout libraries do similar things. I am a fan of <a href="https://github.com/PureLayout/PureLayout">PureLayout</a>. These methods help you create a constraint or two, but wouldn’t be called layout systems on their own.</p>

<p>Higher up the abstraction scale is the Visual Format Language. When I interned at Apple on the Cocoa Frameworks team I helped with the initial implementation of Auto Layout and especially on the parser for the VFL. This lets you specify a few common layouts that can be written as ascii art.</p>

<p>I’ve experimented by <a href="https://github.com/bridger/SwiftVisualFormat">reimplementing some of it in Swift</a> using operator overloading. The idea is the same, but has the advantage of compile-time checking. By glancing at the code you should be able to see the layout.</p>

<figure class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="n">view</span><span class="o">.</span><span class="nf">addConstraints</span><span class="p">(</span><span class="nf">horizontalConstraints</span><span class="p">(</span>
  <span class="o">|-</span><span class="mi">5</span><span class="o">-</span><span class="p">[</span><span class="n">redView</span><span class="p">]</span><span class="o">-</span><span class="mi">0</span><span class="o">-</span><span class="p">[</span><span class="n">greenView</span><span class="p">]</span><span class="o">-</span><span class="mi">0</span><span class="o">-</span><span class="p">[</span><span class="n">blueView</span><span class="p">]</span><span class="o">-</span><span class="mi">5</span><span class="o">-|</span>
<span class="p">))</span></code></pre></figure>

<p>When using the Visual Format Language you aren’t as concerned with each constraint, but the array of constraints is still passed back to you to manage yourself. It would be difficult to find one of those constraints and edit it later.</p>

<p>Even more interesting are libraries that are higher on the ladder of abstraction. <code class="language-plaintext highlighter-rouge">UIStackView</code>, also new in iOS 9, is a great example of this. Internally it uses Auto Layout, but you can get pretty far without ever managing a constraint yourself. Rather than constraints, you are dealing directly with ideas of alignment and spacing. I’ve got a similar layout library, <a href="https://github.com/bridger/StackLayout">StackLayout</a>, which I’d like to talk about more.</p>

<p>Most layouts in practice are some variation on laying out views side-by-side vertically or horizontally in a container. Here is an example from Paper:</p>

<p><img src="/assets/images/stacklayout-tips.png" alt="Welcome to Paper Tip" /></p>

<p>Described in english, this is 4 views arranged vertically. The container fits the contents except for some margins on the sides. There is consistent spacing except between the title and body. This is how it is written with StackLayout:</p>

<figure class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="k">let</span> <span class="nv">verticalLayout</span> <span class="o">=</span> <span class="n">tipView</span><span class="o">.</span><span class="nf">addSubviewsWithVerticalLayout</span><span class="p">(</span>
    <span class="p">[</span><span class="n">titleLabel</span><span class="p">,</span> <span class="n">bodyLabel</span><span class="p">,</span> <span class="n">tipsButton</span><span class="p">,</span> <span class="n">laterButton</span><span class="p">]</span>
<span class="p">)</span> <span class="p">{</span> <span class="n">layout</span> <span class="k">in</span>
    <span class="n">layout</span><span class="o">.</span><span class="n">verticalAlignment</span> <span class="o">=</span> <span class="o">.</span><span class="kt">Fill</span>
    <span class="n">layout</span><span class="o">.</span><span class="n">horizontalMargins</span> <span class="o">=</span> <span class="mi">25</span>
    <span class="n">layout</span><span class="o">.</span><span class="n">topMargin</span> <span class="o">=</span> <span class="mi">34</span>
    <span class="n">layout</span><span class="o">.</span><span class="n">bottomMargin</span> <span class="o">=</span> <span class="mi">17</span>
    <span class="n">layout</span><span class="o">.</span><span class="n">spacing</span> <span class="o">=</span> <span class="mi">21</span>
    <span class="n">layout</span><span class="o">.</span><span class="nf">setSpacing</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="nv">between</span><span class="p">:</span> <span class="n">titleLabel</span><span class="p">,</span> <span class="nv">and</span><span class="p">:</span> <span class="n">bodyLabel</span><span class="p">)</span>
<span class="p">}</span></code></pre></figure>

<p>Not only does this create all of the constraints for you, it returns a layout object which keeps track of those constraints and lets you modify them later. For example, the horizontal margins can be increased.</p>

<figure class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="n">verticalLayout</span><span class="o">.</span><span class="n">horizontalMargins</span> <span class="o">=</span> <span class="mi">55</span></code></pre></figure>

<p>This is pretty similar to other layout systems, such as CSS’s flexbox. The fact that it is built on Auto Layout gives you some great advantages. It is a leaky abstraction in the best way.</p>

<h2 id="sizing-children">Sizing children</h2>

<p>Before Auto Layout, there was only one way to ask a subview what size it prefers to be, <code class="language-plaintext highlighter-rouge">sizeThatFits(size: CGSize)</code>. Container views had to reimplement this method and do the math to combine all children sizes appropriately. This was often a duplication of the layout logic. Now, only “leaf” controls need to implement the Auto Layout <code class="language-plaintext highlighter-rouge">intrinsicContentSize</code> and the same constraints that govern layout also bubble up sizing information with contentFittingSize.</p>

<p>The old <code class="language-plaintext highlighter-rouge">sizeThatFits</code> method also couldn’t express subtleties, like the fact that a slider can be any width greater than ~40 but there is exactly one correct height. Or the way that a button can get smaller than its icon / label if it absolutely needs to (<code class="language-plaintext highlighter-rouge">contentCompressionResistancePriority</code>), or that it can get wider than its perfect size but it would rather not (<code class="language-plaintext highlighter-rouge">contentHuggingPriority</code>).</p>

<p>Sizing children views is no small task and it is a huge advantage that each layout system built on Auto Layout can take it for granted.</p>

<h2 id="exceptions-to-the-rule--priorities">Exceptions to the rule / priorities</h2>

<p>Layout systems usually have a few general rules that take care of most cases. StackLayout is a single row or column with spacing, alignment, and margins. It is a great system that will do absolutely everything you need, unless you are building interfaces meant for humans. Those inevitably have 1000’s of exceptions to the rules.</p>

<p>The exceptions are what make layout so tricky. If a layout system needed to accommodate every edge case the API and complexity would get out of hand. Instead of each layout system handling every exception, Auto Layout gives a convenient way to manually override some detail.</p>

<p>For example, in this login dialog the email field is below the Paper logo, except when it is not:</p>

<p><img src="/assets/images/stacklayout-login.gif" alt="Login Dialog" /></p>

<p>What vertical alignment should I use there? In StackLayout I can have it be top-aligned with a low priority, and then use a higher-priority constraint to move the email field below the logo. Additionally, I’ll need to override the width of the buttons to be equal widths.</p>

<figure class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="n">loginView</span><span class="o">.</span><span class="n">layoutMargins</span> <span class="o">=</span> <span class="kt">UIEdgeInsets</span><span class="p">(</span><span class="nv">top</span><span class="p">:</span> <span class="mf">30.0</span><span class="p">,</span>  <span class="nv">left</span><span class="p">:</span> <span class="mf">20.0</span><span class="p">,</span>
                                    <span class="nv">bottom</span><span class="p">:</span> <span class="mf">20.0</span><span class="p">,</span> <span class="nv">right</span><span class="p">:</span> <span class="mf">20.0</span><span class="p">)</span>

<span class="n">loginView</span><span class="o">.</span><span class="nf">addSubviewsWithVerticalLayout</span><span class="p">(</span>
    <span class="p">[</span><span class="n">logoView</span><span class="p">]</span>
<span class="p">)</span> <span class="p">{</span> <span class="n">layout</span> <span class="k">in</span>
    <span class="n">layout</span><span class="o">.</span><span class="n">layoutMarginsRelativeArrangement</span> <span class="o">=</span> <span class="kc">true</span>
    <span class="n">layout</span><span class="o">.</span><span class="n">verticalAlignment</span> <span class="o">=</span> <span class="o">.</span><span class="kt">Top</span>
    <span class="n">layout</span><span class="o">.</span><span class="n">horizontalAlignment</span> <span class="o">=</span> <span class="o">.</span><span class="kt">Center</span>
<span class="p">}</span>

<span class="n">loginView</span><span class="o">.</span><span class="nf">addSubviewsWithVerticalLayout</span><span class="p">(</span>
    <span class="p">[</span><span class="n">emailField</span><span class="p">,</span> <span class="n">orLabel</span><span class="p">,</span> <span class="n">googleButton</span><span class="p">,</span> <span class="n">facebookButton</span><span class="p">]</span>
<span class="p">)</span> <span class="p">{</span> <span class="n">layout</span> <span class="k">in</span>
    <span class="n">layout</span><span class="o">.</span><span class="n">layoutMarginsRelativeArrangement</span> <span class="o">=</span> <span class="kc">true</span>
    <span class="n">layout</span><span class="o">.</span><span class="n">horizontalAlignment</span> <span class="o">=</span> <span class="o">.</span><span class="kt">Center</span>
    <span class="c1">// Top-aligned but with a low priority to be overriden</span>
    <span class="n">layout</span><span class="o">.</span><span class="n">verticalAlignment</span> <span class="o">=</span> <span class="o">.</span><span class="kt">Top</span>
    <span class="n">layout</span><span class="o">.</span><span class="n">marginsPriority</span> <span class="o">=</span> <span class="kt">UILayoutPriorityDefaultLow</span>
    <span class="n">layout</span><span class="o">.</span><span class="n">spacing</span> <span class="o">=</span> <span class="mi">10</span>
<span class="p">}</span>

<span class="k">let</span> <span class="nv">logoToEmail</span> <span class="o">=</span> <span class="n">emailField</span><span class="o">.</span><span class="n">bottomAnchor</span>
    <span class="o">.</span><span class="nf">constraintEqualToAnchor</span><span class="p">(</span><span class="n">logoView</span><span class="o">.</span><span class="n">bottomAnchor</span><span class="p">,</span> <span class="nv">constant</span><span class="p">:</span> <span class="mi">30</span><span class="p">)</span>
<span class="n">logoToEmail</span><span class="o">.</span><span class="n">active</span> <span class="o">=</span> <span class="kc">true</span> <span class="c1">// Deactivate to let the controls float to the top</span>

<span class="c1">// Other exceptions to the layout</span>
<span class="n">orLabel</span><span class="o">.</span><span class="n">heightAnchor</span><span class="o">.</span><span class="nf">constraintEqualToConstant</span><span class="p">(</span><span class="mi">50</span><span class="p">)</span><span class="o">.</span><span class="n">active</span> <span class="o">=</span> <span class="kc">true</span>
<span class="n">googleButton</span><span class="o">.</span><span class="n">widthAnchor</span>
    <span class="o">.</span><span class="nf">constraintEqualToAnchor</span><span class="p">(</span><span class="n">facebookButton</span><span class="o">.</span><span class="n">widthAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">active</span> <span class="o">=</span> <span class="kc">true</span>
<span class="n">googleButton</span><span class="o">.</span><span class="n">widthAnchor</span><span class="o">.</span><span class="nf">constraintEqualToConstant</span><span class="p">(</span><span class="mi">185</span><span class="p">)</span></code></pre></figure>

<h2 id="cross-layout-constraints">Cross-layout constraints</h2>

<p>Auto Layout lets views position relative to each other even if they don’t share a layout manager or if they have have different superviews.</p>

<p>The login dialog earlier has a Continue and Cancel button which should line up with existing buttons during the animation. There is also a loading indicator that might show where the Continue button is.</p>

<p><img src="/assets/images/stacklayout-login-loading.png" alt="Login Dialog Loading" /></p>

<p>I can use the earlier layout without changing it and add the three new controls. There are ways to hack this in other layout systems using wrapper views, but Auto Layout makes it pretty natural.</p>

<figure class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="c1">// Align Continue with Google</span>
<span class="n">continueButton</span><span class="o">.</span><span class="n">centerXAnchor</span><span class="o">.</span><span class="nf">constraintEqualToAnchor</span><span class="p">(</span>
    <span class="n">googleButton</span><span class="o">.</span><span class="n">centerXAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">active</span> <span class="o">=</span> <span class="kc">true</span>
<span class="n">continueButton</span><span class="o">.</span><span class="n">centerYAnchor</span><span class="o">.</span><span class="nf">constraintEqualToAnchor</span><span class="p">(</span>
    <span class="n">googleButton</span><span class="o">.</span><span class="n">centerYAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">active</span> <span class="o">=</span> <span class="kc">true</span>

<span class="c1">// Align Cancel with Facebook</span>
<span class="n">cancelButton</span><span class="o">.</span><span class="n">centerXAnchor</span><span class="o">.</span><span class="nf">constraintEqualToAnchor</span><span class="p">(</span>
    <span class="n">facebookButton</span><span class="o">.</span><span class="n">centerXAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">active</span> <span class="o">=</span> <span class="kc">true</span>
<span class="n">cancelButton</span><span class="o">.</span><span class="n">centerYAnchor</span><span class="o">.</span><span class="nf">constraintEqualToAnchor</span><span class="p">(</span>
    <span class="n">facebookButton</span><span class="o">.</span><span class="n">centerYAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">active</span> <span class="o">=</span> <span class="kc">true</span>

<span class="c1">// Align loading indicator with Continue</span>
<span class="n">loadingIndicator</span><span class="o">.</span><span class="n">centerXAnchor</span><span class="o">.</span><span class="nf">constraintEqualToAnchor</span><span class="p">(</span>
    <span class="n">continueButton</span><span class="o">.</span><span class="n">centerXAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">active</span> <span class="o">=</span> <span class="kc">true</span>
<span class="n">loadingIndicator</span><span class="o">.</span><span class="n">centerYAnchor</span><span class="o">.</span><span class="nf">constraintEqualToAnchor</span><span class="p">(</span>
    <span class="n">continueButton</span><span class="o">.</span><span class="n">centerYAnchor</span><span class="p">)</span><span class="o">.</span><span class="n">active</span> <span class="o">=</span> <span class="kc">true</span>

<span class="c1">// Later, use alpha to fade the buttons in and out</span></code></pre></figure>

<h2 id="pixel-integralization">Pixel Integralization</h2>

<p>“Pixel-integralization” is making sure that frames of components fall on pixel boundaries, rather than a blurry line in between two pixels. This is trickier than it sounds — if you just round all of the frames you won’t get the best results. Auto Layout has the global knowledge needed to make everything fall on pixel boundaries even on the iPhone 6+ where each point is 2.6 pixels.</p>

<h2 id="rtl-languages">RTL languages</h2>

<p>Another tricky issue is support for RTL languages. When you read right-to-left, it makes sense to switch the entire interface so labels are on the right and actions are on the left. If you use the Leading and Trailing attributes on Auto Layout this is done automatically for you.</p>

<div class="breaker"></div>

<p>If you’ve liked these examples, <a href="https://github.com/bridger/StackLayout">give StackLayout a try</a>. It is available on CocoaPods, where I hope to see more layout systems built on the Auto Layout engine too.</p>]]></content><author><name></name></author><category term="open source" /><category term="StackLayout" /><category term="Auto Layout" /><summary type="html"><![CDATA[Auto Layout is the constraint-based layout framework for iOS and OS X. At its core it replaces setFrame with addConstraint. Where you would previuosly give the exact coordinates of a view, now you describe the view’s location in relation to other views. It is common to use addConstraint directly, but Auto Layout is actually a great engine to build layout systems on top of. In this post I’ll talk about different abstraction layers on Auto Layout and show its advantages with my library StackLayout.]]></summary></entry><entry><title type="html">Light Field Capture</title><link href="http://bridgermaxwell.com/blog/light-field-capture/" rel="alternate" type="text/html" title="Light Field Capture" /><published>2011-12-06T12:00:00-05:00</published><updated>2011-12-06T12:00:00-05:00</updated><id>http://bridgermaxwell.com/blog/light-field-capture</id><content type="html" xml:base="http://bridgermaxwell.com/blog/light-field-capture/"><![CDATA[<p><a href="http://www.lytro.com/">Lytro</a> recently released the first consumer “light field camera.” This means that the camera not only captures what position each light ray hits the sensor, but also the angle of each light ray. Imagining what a light field is, why this data is useful, and how it is transformed can be a difficult hurdle to overcome. Once it is understood, light fields can be really useful. I added a light field sensor to my Optic Workbench application, and explored using that sensor to capture information about a difracting surface.</p>

<p>While a photograph has 4 dimensions (x, y, intensity, color), a light field of the same scene has 6 dimensions (x, y, Θ1, Θ2, instensity, color). That is a lot of information! Optics Workbench works with 2 dimensonal scenes, which are easier to manage. A “photograph” in this 2D environment has 3 dimensions (x, intensity, color), and a light field has 4 dimensions (x, Θ, intensity, color). Mapping Θ to the y-axis, and this can be visualized in a graph.</p>

<p><img src="/assets/images/optic-workbench-light-field.png" alt="Optic Workbench Graph" /></p>

<p>You can try this out for yourself in <a href="/blog/optic-workbench-source/">Optic Workbench</a>. The sensor is the component with a white side and a black side. The white strip captures light rays. Clicking on the sensor shows the light field graph. Notice how the graph is transformed when you move or rotate the sensor. You can apply these transformations digitally after the light field is captured. For example, digitally moving the sensor to refocus the image. This is what the Lytro has done.</p>]]></content><author><name></name></author><category term="open source" /><category term="optics" /><category term="playground" /><summary type="html"><![CDATA[Lytro recently released the first consumer “light field camera.” This means that the camera not only captures what position each light ray hits the sensor, but also the angle of each light ray. Imagining what a light field is, why this data is useful, and how it is transformed can be a difficult hurdle to overcome. Once it is understood, light fields can be really useful. I added a light field sensor to my Optic Workbench application, and explored using that sensor to capture information about a difracting surface.]]></summary></entry><entry><title type="html">Optic Workbench</title><link href="http://bridgermaxwell.com/blog/optic-workbench-source/" rel="alternate" type="text/html" title="Optic Workbench" /><published>2011-10-28T12:00:00-04:00</published><updated>2011-10-28T12:00:00-04:00</updated><id>http://bridgermaxwell.com/blog/optic-workbench-source</id><content type="html" xml:base="http://bridgermaxwell.com/blog/optic-workbench-source/"><![CDATA[<p>Optic Workbench is an application on OS X that lets you play with simple optic toys. You have light sources, lenses, flat and curved mirrors, beam splitters, and obstacles.</p>

<p><img src="/assets/images/optic-workbench.png" alt="Optic Workbench Screenshot" /></p>

<p>I spent a lot of time making sure it was easy to manipulate the tools on the workbench. Drag a new one from the library in the bottom left. You can move it by dragging near the center of the tool. You can rotate it by dragging on the purple circle. You can resize by stretching the tool. You can modify the focal length of a lens or parabolic mirror by a simple drag.</p>

<p>The simulation is very straightforward. It works like this:</p>

<ul>
  <li>First, each tool on the board has a chance to emit “starting rays”. These are added to a list of active rays. Each ray has a starting position (x,y), an angle, and a color.</li>
  <li>Now the simulation enters a loop. One of the active rays is chosen and removed from the list. The distance to each tool is computed, and the closest intersecting tool is chosen. A line is drawn from the origin to the intersection point.</li>
  <li>The tool that the ray hits then has a chance to “transform” the ray, and return an array of new rays. For example, a mirror will return a new ray starting on the mirror, and with the reflected angle. A beam splitter returns two rays. One is reflected, and one continues on the same path. Each is half the intensity of the original ray. These transformed rays are added to the list of active rays, and the loop continues until all active rays are gone.</li>
  <li>The application requires OS X Lion (10.7) to run.</li>
</ul>

<p><a href="https://github.com/bridger/optic-workbench">Get a copy of the source code on GitHub</a></p>

<p><a href="/assets/OpticWorkbench-Built.zip">Download the application</a></p>]]></content><author><name></name></author><category term="open source" /><category term="optics" /><category term="playground" /><summary type="html"><![CDATA[Optic Workbench is an application on OS X that lets you play with simple optic toys. You have light sources, lenses, flat and curved mirrors, beam splitters, and obstacles.]]></summary></entry></feed>