## On Coding IX: Computer Graphics I

It has been some time since an On Coding installment, and I thought it finally time to discuss computer graphics.  Of course I’ve done that a lot already, as far as several applications go.  For this post, I asked myself something different:  what do I use computer graphics for?

I had never really taken a step back to look at the larger picture, but that’s one of the purposes of this thread.  I came up with seven major uses, in roughly chronological order from when I started using graphics in each way:

1. Creating fractals.
2. Graphic design.
3. Rendering polyhedra in three dimensions.
4. Mathematical illustration.
5. Web design.
6. Mathematical art.
7. Research.

Today, I’ll give a brief overview, and follow up in future posts with more details about the various platforms I’ve used.

I don’t need to say a lot about the first two uses, since I’ve discussed them in some detail in my posts on Postscript and iterated function systems.  My interest in fractals has of course continued, especially given my passion for Koch curves and binary trees.  I work less with graphic design now — I used to design stationery and business cards for myself and friends, but now that communication is so largely electronic, there is less of a need.  But I do still occasionally design business cards using my art logo, print them onto cardstock, and cut them myself when I need to.

I also spend quite a bit of time designing title and separator slides for presentations.  (I frankly admit to never having created a PowerPoint presentation in my entire life.  Yuck.)  I now exclusively use TikZ in LaTeX since you have complete control over the graphics environment.

I haven’t mentioned polyhedra extensively on my blog so far, but my interest in three-dimensional geometry goes back to my undergraduate days.  When I started teaching college for the first time, I designed (and eventually wrote a textbook for) a course on polyhedra based on spherical trigonometry.

The main tool I used early on was Mathematica, and when I redid all my graphics for my textbook about five years ago, I used Mathematica.  The image you see above was rendered using POV-Ray, a ray-tracing package which allows the user to specify a wide range of parameters to create realistic effects.  You can see shadows and a reflection as if the polyhedron were sitting on a shiny, black surface.  And while the images generated by POV-Ray are quite a bit nicer than those created with Mathematica, they take more time and effort to create.

Mathematical illustration covers a wide range of uses.  Drawing figures for a mathematical paper perhaps first comes to mind.  I used a package called PSTricks for quite a while (since the “PS” stands for Postscript), but once I learned about TikZ, I changed over fairly quickly.  This means I needed to re-render many older graphics (especially in my textbook) — but since for both packages you need precise coordinates, I already had all the mathematics worked out for the PSTricks function calls.  So converting to TikZ wasn’t all that problematic.  I will be talking in more detail about TikZ in a future post.

Of course there are also geometrical puzzles and problems, as I’ve discussed before on my blog.  Nicely formatted graphics go a long way in making a puzzle appealing to the reader.

Web design is especially important, since I rely so much on my website for everything.  I have a web page for my artwork, for my publications, talks, and anything I do professionally.  I strive for functionality and aesthetics.  I’m also a minimalist as far as design goes — “less is more.”

Also important is ease of use for me.  It’s not hard to add something to my homepage.  I don’t have the time (or interest) in redesigning my homepage every I want to add a new link.  I’m not a fan of hiding everything in dropdown menus — I want the user to glance at my site, and immediately click on the relevant link without having to pore through menus.

Mathematical art has actually been a fairly recent use of computer graphics for me — I only really started getting into it about four years ago.  I don’t feel I have to say a lot about it right here, since it is a common thread throughout so many of my posts.  You can visit my art website, or look at my Twitter, where I try to update daily (as much as I can) with new and interesting pieces of mathematical art.

Finally, I’d like to say a word about the last use of computer graphics:  research.   I think this is extremely important, especially with the exploding world of data visualization.  Really, this has been perhaps Nick’s and my most important tool when it comes to studying binary trees.

Without going into too much detail about this image, is consists of six scaled and rotated copies of one tree (the ones in color) and a related dual tree (in white).  Now count the number of leaves (ends of paths) in common with the colorful trees — and you’ll count 1, 5, 10, 10, 5, and 1.  These are, of course, binomial coefficients:  row 5 of Pascal’s triangle.

Why is this the case?  And is there some general result to be proved?  The point I’m making is that when Nick and I create routines to display different trees or combinations of trees, we look at lots of examples, and seek recurring themes.

We learn a lot by doing this, and the direction of our research is heavily influenced by what we observe.  This might not be so surprising, since after all, fractal trees are such geometrical objects.  I can honestly say the pace of our progress in making conjectures is directly linked to our ability to produce large numbers of trees and knowing what to look for.

So that’s what I use computer graphics for!  In future posts, I’ll discuss the various software packages I use, and try to give some idea of the advantages and disadvantages of each.  I’ll give special emphasis to those that are open-source — there is so much out there that is free to download, anyone interesting in computer graphics will have no difficulty finding something interesting to experiment with!

## Imagifractalous! 6: Imagifractalous!

No, the title of today’s post is not a typo….

About a month ago, a colleague who takes care of the departmental bulletin boards in the hallway approached me and asked if I’d like to create a bulletin board about mathematical art.  There was no need to think it over — of course I would!

Well, of course we would, since I immediately recruited Nick to help out.  We talked it over, and decided that I would describe Koch-like fractal images on the left third of the board, Nick would discuss fractal trees on the right third, and the middle of the bulletin board would highlight other mathematical art we had created.

I’ll talk more about the specifics in a future post — especially since we’re still working on it!  But this weekend I worked on designing a banner for the bulletin board, which is what I want to share with you today.

I really had a lot of fun making this!  I decided to create fractals for as many letters of Imagifractalous! as I could, and use isolated letters when I couldn’t.  Although I did opt not to use a third fractal “A,” since I already had ideas for four fractal letters in the second line.

The “I”‘s came first.  You can see that they’re just relatively ordinary binary trees with small left and right branching angles.  I had already incorporated the ability to have the branches in a tree decrease in thickness by a common ratio with each successive level, so it was not difficult to get started.

I did use Mathematica to help me out, though, with the spread of the branches.  Instead of doing a lot of tweaking with the branching angles, I just adjusted the aspect ratio (the ratio of the height to the width of the image) of the displayed tree.  For example, if the first “I” is displayed with an aspect ratio of 1, here is what it would look like:

I used an aspect ratio of 6 to get the “I” to look just like I wanted.

Next were the “A”‘s.  The form of an “A” suggested an iterated function system to me, a type of transformed Sierpinski triangle.  Being very familiar with the Sierpinski triangle, it wasn’t too difficult to modify the self-similarity ratios to produce something resembling an “A.”  I also like how the first “A” is reminiscent of the Eiffel Tower, which is why I left it black.

I have to admit that discovering the “R” was serendipitous.  I was reading a paper about trees with multiple branchings at each node, and decided to try a few random examples to make sure my code worked — it had been some time since I tried to make a tree with more than two branches at each node.

When I saw this, I immediately thought, “R”!  I used this image in an earlier draft, but decided I needed to change the color scheme.  Unfortunately, I had somehow overwritten the Mathematica notebook with an earlier version and lost the code for the original “R,” but luckily it wasn’t hard to reproduce since I had the original image.  I knew I had created the branches only using simple scales and rotations, and could visually estimate the original parameters.

The “C” was a no-brainer — the fractal C-curve!  This was fairly straightforward since I had already written the Mathematica code for basic L-systems when I was working with Thomas last year.  This fractal is well-known, so it was an easy task to ask the internet for the appropriate recursive routine to generate the C-curve:

+45  F  -90  F  +45

For the coloring, I used simple linear interpolation from the RGB values of the starting color to the RGB values of the ending color.  Of course there are many ways to use color here, but I didn’t want to spend a lot of time playing around.  I was pleased enough with the result of something fairly uncomplicated.

For the “T,” it seemed pretty obvious to use a binary tree with branching angles of 90° to the left and right.  Notice that the ends of the branches aren’t rounded, like the “I”‘s; you can specify these differences in Mathematica.  Here, the branches are emphasized, not the leaves — although I did decide to use small, bright red circles for the leaves for contrast.

The “L” is my favorite letter in the entire banner!  Here’s an enlarged version:

This probably took the longest to generate, since I had never made anything quite like it before.  My inspiration was the self-similarity of the L-tromino, which may be made up of four smaller copies of itself.

The problem was that this “L” looked too square — I wanted something with a larger aspect ratio, but keeping the same self-similarity as much as possible.  Of course exact self-similarity isn’t possible in general, so it took a bit of work to approximate is as closely as I could.  I admit the color scheme isn’t too creative, but I liked how the bold, primary colors emphasized the geometry of the fractal.

The “O” was the easiest of the letters — I recalled a Koch-like fractal image I created earlier which looked like a wheel with spokes and which had a lot of empty space in the interior.  All I needed to do was change the color scheme from white-on-gray  to black-on-white.

Finally, the “S.”  This is the fractal S-curve, also known as Heighway’s dragon.  It does help to have a working fractal vocabulary — I knew the S-curve existed, so I just asked the internet again….  There are many ways to generate it, but the easiest for me was to recursively producing a string of 0’s and 1’s which told me which way to turn at each step.  Easy from there.

So there it is!  Took a lot of work, but it was worth it.  I’ll take a photo when it’s actually displayed — and update you when the entire bulletin board is finally completed.  We’ve only got until the end of the semester, so it won’t be too long….

## Imagifractalous! 5: Binary Trees III

Last week I talked about working with binary trees whose branching ratio is 1 or greater.  The difficulty with having a branching ratio larger than one is that the tree keeps growing, getting larger and larger with each iteration.

But when you work with software like Mathematica, for example, and you create such a tree, you can specify the size of the displayed image in screen size.

So the trees above both have branching ratio 2 and branching angle of 70°.  The left image is drawn to a depth of 7, and the right image is drawn to a depth of 12.  I specified that both images be drawn the same size in Mathematica.

But even though they are visually the same size, if you start with a trunk 1 unit in length, the left image is about 200 units wide, while the second is 6000 units wide!

So this prompted us to look at scaling back trees with large branching ratios.  In other words, as trees kept getting larger, scale them back even more.  You saw why this was important last week:  if the scale isn’t right, when you overlap trees with r less than one on top of the reciprocal tree with branching ratio 1/r, the leaves of the trees won’t overlap.  The scale has to be just right.

So what should these scale factors be?  This is such an interesting story about collaboration and creativity — and how new ideas are generated — that I want to share it with you.

For your usual binary tree with branching ratio less than one, you don’t have to scale at all.  The tree remains bounded, which is easy to prove using convergent geometric series.

What about the case when r is exactly 1, as shown in the above figure?  At depth n, if you start with a trunk of length 1, the path from the base of the trunk to the leaf is a path of exactly n + 1 segments of length 1, and so can’t be any longer than n + 1 in length.  As the branching angle gets closer to 0°, you do approach this bound of n + 1.  So we thought that scaling back by a factor of n + 1 would keep the tree bounded in the case when r is 1.

What about the case when r > 1?  Let’s consider the case when r = 2 as an example.  The segments in any path are of length 1, 2, 4, 8, 16, etc., getting longer each time by a power of 2.  Going to a depth of n, the total length is proportional to $2^n$ in this case.  In general, the total length is about $2\cdot r^n$ for arbitrary r, so scaling back by a factor of $r^n$ would keep the trees bounded as well.

So we knew how to keep the trees bounded, and started including these scaling factors when drawing our images.  But there were two issues.  First, we still had to do some fudging when drawing trees together with their reciprocal trees.  We could still create very appealing images, but we couldn’t use the scale factor on its own.

And second — and perhaps more importantly — Nick had been doing extensive exploration on his computer generating binary trees.  Right now, we had three different cases for scaling factors, depending on whether r < 1, r = 1, or r > 1.  But in Nick’s experience, when he moved continuously through values of r less than 1 to values of r greater than one, the transition looked very smooth to him.  There didn’t seem to be any “jump” when passing through r = 1, as happened with the scale factors we had at the moment.

I wasn’t too bothered by it, though.  There are lots of instances in mathematics where 1 is some sort of boundary point.  Take geometric series, for example.  Or perhaps there is another boundary point which separates three fundamentally different types of solutions.  For example, consider the quadratic equation

$x^2+c=0.$

The three fundamentally different solution sets correspond to  c < 0, c = 0, and c > 0.  There is a common example from differential equations, too, though I won’t go into that here.  Suffice it to say, this type of trichotomy occurs rather frequently.

I tried explaining this to Nick, but he just wouldn’t budge.  He had looked at so many binary trees, his intuition led him to firmly believe there just had to be a way to unify these scale factors.

I can still remember the afternoon — the moment — when I saw it.  It was truly beautiful, and I’ll share it in just a moment.  But my point is this:  I was so used to seeing trichotomies in mathematics, I was just willing to live with these three scale factors.  But Nick wasn’t.  He was tenacious, and just insisted that there was further digging to do.

Don’t ask me to explain how I came up with it.  It was like that feeling when you just were holding on to some small thing, and now you couldn’t find it.  But you never left the room, so it just had to be there.  So you just kept looking, not giving up until you found it.

And there is was:  if the branching ratio was and you were iterating to a depth of n, you scaled back by a factor of

$\displaystyle\sum_{k=0}^n r^k.$

This took care of all three cases at once!  When r < 1, this sum is bounded (think geometric series), so the boundedness of the tree isn’t affected.  When r = 1, you just get n + 1 — the same scaling factor we looked at before!  And when r > 1, this sum is large enough to scale back your tree so it’s bounded.

Not only that, this scale factor made proving the Dual Tree Theorem so nice.  The scaling factors for a tree with r < 1 and its reciprocal tree with branching ratio 1/r matched perfectly.  No need to fudge!

This isn’t the place to go into all the mathematics, but I’d be happy to share a copy of our paper if you’re interested.  We go into a lot more detail than I ever could in a blog post.

This is how mathematics happens, incidentally.  It isn’t just a matter of finding a right answer, or just solving an equation.  It’s a give-and-take, an exploration, a discovery here and there, tenacity, persistence.  A living, breathing endeavor.

But the saga isn’t over yet….  There is a lot more to say about binary trees.  I’ll do just that in my next installment of Imagifractalous!

## Imagifractalous! 4: Fractal Binary Trees II

Now that the paper Nick and I wrote on binary trees was accepted for Bridges 2017 (yay!), I’d like to say a little more about what we discovered.  I’ll presume you’ve already read the first Imagifractalous! post on binary trees (see Day077 for a refresher if you need it).

Recall that in that post, I discussed creating binary trees with branching ratios which were 1 or larger.  Below are three examples of binary trees, with branching ratios less that 1, equal to 1, and larger than 1, respectively.

It was Nick’s insight to consider the following question:  how are trees with branching ratio r related to those with branching ratio 1/r?  He had done a lot of exploring with graphics in Python, and observed that there was definitely some relationship.

Let’s look at an example.  The red tree is a binary tree with branching ratio r less than one, and the gray tree has a branching ratio which is the reciprocal r.  Both are drawn to the same depth.

Of course you notice what’s happening — the leaves of the trees are overlapping!  This was happening so frequently, it just couldn’t be coincidence.  Here is another example.

Notice how three copies of the trees with branching ratio less than one are covering some of the leaves of a tree with the reciprocal ratio.

Now if you’ve ever created your own binary trees, you’ll likely have noticed that I left out a particularly important piece of information:  the size of the trunks of the trees.  You can imagine that if the sizes of the trunks of the r trees and the 1/r trees were not precisely related, you wouldn’t have the nice overlap.

Here is a figure taken from our paper which explains just how to find the correct relationship between the trunk sizes.  It illustrates the main idea which we used to rigorously prove just about everything we observed about these reciprocal trees.

Let’s take a look at what’s happening.  The thick, black tree has a branching ratio of 5/8, and a branching angle of 25°.  The thick, black path going from O to P is created by following the sequence of instructions RRRLL (and so the tree is rendered to a depth of 5).

Now make a symmetric path (thick, gray, dashed) starting at P and going to O.  If we start at P with the same trunk length we started with at O, and follow the exact same instructions, we have to end up back at O.

The trick is to now look at this gray path backwards, starting from O.  The branches now get larger each time, by a factor of 8/5 (since they were getting smaller by a factor of 5/8 when going in the opposite direction).  The size of the trunk, you can readily see, is the length of the last branch drawn in following the black path from O to P.  This must be (5/8)5 times the length of the trunk, since the tree is of depth 5.

The sequence of instructions needed to follow this gray path is RRLLL.  It turns out this is easy to predict from the geometry.  Recall that beginning at P, we followed the instructions RRRLL along the gray path to get to O.  When we reverse this path and go from O to P, we follow the instructions in reverse — except that in going in the reverse direction, what was previously a left turn becomes a right turn, and vice versa.

So all we need to do to get the reverse instructions is to reverse the string RRRLL to get LLRRR, and then change the L‘s to R‘s and the R‘s to L‘s, yielding RRLLL.

There’s one important detail to address:  the fact that the black tree with branching ratio 5/8 is rotated by 25° to make everything work out.  Again, this is easy to see from the geometry of the figure.  Look at the thick gray path for a moment.  Since following the instructions RRLLL means that in total, you make one more left turn than you do right turns, the last branch of the path must be oriented 25° to the left of your starting orientation (which was vertical).  This tells you precisely how much you need to rotate the black tree to make the two paths have the same starting and ending points.

Of course one example does not make a proof — but in fact all the important ideas are contained in this one illustration.  It is not difficult to make the argument more general, and we have successfully accomplished that (though this blog is not the place for it!).

If you look carefully at the diagram, you’ll count that there are exactly 10 leaves in common with these two trees with reciprocal branching ratios.  There is some nice combinatorics going on here, which is again easy to explain from the geometry.

You can see that these common leaves (illustrated with small, black dots) are at the ends of gray branches which are oriented 25° from the vertical.  Recall that this specific angle came from the fact that there was one more L than there were R‘s in the string RRLLL.

Now if you have a sequence of 5 instructions, the only way to have exactly one more L than R‘s is to have precisely three L‘s (and hence two R‘s).  And the number of ways to have three L‘s in a string of length 5 is just

$\displaystyle{5\choose3}=10.$

Again, these observations are easy to generalize and prove rigorously.

And where does this take us?

On the right are 12 copies of a tree with a braching ratio of r less than one and a branching angle of 30°, and on the left are 12 copies of a tree with a reciprocal branching ratio of 1/r, also with a branching angle of 30°.  All are drawn to depth 4, and the trunks are appropriately scaled as previously discussed.

These sets of trees produce exactly the same leaves!  We called this the Dual Tree Theorem, which was the culmination of all these observations.  Here is an illustration with both sets of trees on top of each other.

As intriguing as this discovery was, it was only the beginning of a much broader and deeper exploration into the fractal world of binary trees.  I’ll continue a discussion of our adventures in the next installment of Imagifractalous!

## Imagifractalous! 3: Fractal Binary Trees

I’ve taken a break from Koch-like curves and p-adic sequences for an arboreal interlude….  Yes, there’s a story about why — I needed to work with Nick on a paper he was writing for Bridges — but that story isn’t quite finished yet.  When it is, I’ll tell it.  But for now, I thought I’d share some of the fascinating images we created along the way.

Let’s start with a few examples of simple binary trees.  If you want to see more, just do a quick online search — there are lots of fractal trees out there on the web!  The construction is pretty straightforward.  Start by drawing a vertical trunk of length 1.  Then, move left and right some specified angle, and draw a branch of some length r < 1.  Recursively repeat from where you left off, always adding two more smaller branches at the tip of each branch you’ve already drawn.

If you look at these two examples for a moment, you’ll get the idea.  Here, the angle used is 40 degrees, and the ratio is 5/8.  On the left, there are 5 iterations of the recursive drawing, and there are 6 iterations on the right.

Here’s another example with a lot more interaction among the branches.

This type of fractal binary tree has been studied quite a bit.  There is a well-known paper by Mandelbrot and Frame which discusses these trees, but it’s not available without paying for it.  So here is a paper by Pons which addresses the same issues, but is available online.  It’s an interesting read, but be forewarned that there’s a lot of mathematics in it!

In trying to understand various properties of these fractal trees, it’s natural to write code which creates them.  But here’s the interesting thing about writing programs like that — once they’re written, you can input anything you like!  Who says that r has to be less than 1?  The tree above is a nice example of a fractal tree with r = 1.  All the branches are of the same length, and there is a lot of overlap.  This helps create an interesting texture.

But here’s the catch.  The more iterations you go, the bigger the tree gets.  In a mathematical sense, the iterations are said to be unbounded.  But when Mathematica outputs a graphic, it is automatically scaled to fit your viewing window.  So in practice, you don’t really care how large the tree gets, since it will automatically be scaled down so the entire tree is visible.

It is important to note that when r < 1, the trees are bounded, so they are easier to study mathematically.  The paper Nick and I are working on scales unbounded trees so they are more accessible, but as I said, I’ll talk more about this in a later post.

Here are a few examples with r > 1.  Notice that as there are more and more iterations, the branches keep getting larger.  This creates a very different type of binary tree, and again, a tree which keeps getting bigger (and unbounded) as the number of iterations increases.  But as mentioned earlier, Mathematica will automatically scale an image, so these trees are easy to generate and look at.

Nick created the following image using copies of binary trees with r approximately equal to 1.04.  The ever-expanding branches allow for the creation of interesting textures you really can’t achieve when r < 1.

Another of my favorites is the following tree, created with r = 1.  The angle used, though, is 90.9 degrees.  Making the angle just slightly larger than a right angle creates an interesting visual effect.

But the exploration didn’t stop with just varying r so it could take on values 1 or greater.  I started thinking about other ways to alter the parameters used to create fractal binary trees.

For example, why does r have to stay the same at each iteration?  Well, it doesn’t!  The following image was created using values of r which alternate between iterations.

And the values of r can vary in other ways from iteration to iteration.  There is a lot more to investigate, such as generating a binary tree from any sequence of r values.  But studying these mathematically may be somewhat more difficult….

Now in a typical binary tree, the angle you branch to the left is the same as the angle you branch to the right.  Of course these two angles don’t have to be the same.  What happens if the branching angle to the left is different from the branching angle to the right?  Below is one possibility.

And for another possibility?  What if you choose two different angles, but have the computer randomly decide which is used to branch left/right at each iteration?  What then?

Here is one example, where the branching angles are 45 and 90 degrees, but which is left or right is chosen randomly (with equal probability) at each iteration.  Gives the fractal tree a funky feel….

You might have noticed that none of these images are in color.  One very practial reason is that for writing Bridges papers, you need to make sure your images look OK printed in black-and-white, since the book of conference papers is not printed in color.

But there’s another reason I didn’t include color images in this post.  Yes, I’ve got plenty…and I will share them with you later.  What I want to communicate is the amazing variety of textures available by using a simple algorithm to create binary trees.  Nick and I never imagined there would be such a fantastic range of images we could create.  But there are.  You’ve just seen them.

Once the Bridges paper is submitted, accepted (hopefully!), and revised, I’ll continue the story of our arboreal adventure.  There is a lot more to share, and it will certainly be worth the wait!

## Koch Curves and Canopies

Time for another “math in the moment” post!  There have been a few interesting developments just this past week, so I thought I’d share them with you.

The first revolves around the Koch curve.  I’ve talked a lot about the algorithm used to generate the Koch curve when the angles are changed — but this is the first time I’ve experimented with three different angles.  For example, the recursive procedure

F   +45   F   +180   F   +315   F

generates the following spiral:

Looks simple, right?  Just 16 line segments.  But here’s the unexpected part — it takes 21,846 iterations to make!  That’s right — the horizontal segment in the upper left is the 21,846th segment to be drawn.

Why might this be?  Partly because of the fact that one angle is 180, and also the fact that 45 + 415 = 360.  In other words, you are often just turning around and retracing your steps.  These arms are retraced multiple times, not just once or twice like in previous explorations.

I found this family of spirals by having Mathematica generate random angles and using the algorithm to draw the curves.  Without going into too many details, the “obvious” way to generalize the equation I came up with before didn’t work, so I resorted to trial and error — which is easy to do when the computer does all the work!

Notice the pattern in the angles:  45 (1/8 of a circle), 180 (1/2 of a circle), and 315 (7/8 of a circle).  Moving up to tenths, we get angles of 36 (1/10 of a circle), 180 (1/2 of a circle), and 324 (9/10 of a circle), which produce the image below.

Notice there are only five arms this time (not 10).  And it only takes 342 segments to draw!  There’s an alternating pattern here.  Moving up to twelfths gives 12 arms, and takes a staggering 5,592,406 segments to draw.  Yes, it really does take almost 6,000,000 iterations to draw the 24th and last segment!

With the help of Mathematica, though, I did find explicit formulas to calculate exactly how many iterations it will take to draw each type of image, depending on whether there are an even number of arms, or an odd number.  Now the hard part — prove mathematically why the formulas work!  That’s the next step.

I hope this “simple” example illustrates how much more challenging working with three different angles will be.  I think working out the proof in these cases will give me more insight into how the algorithm with three angles works in general, and might help me derive an equation analogous to the case when the first and third angles are the same.

The second development is part of an ongoing project with Nick to write a paper for the Bridges 2017 conference in Waterloo.  The project revolves around fractal trees generated by L-systems.  (We won’t be discussing L-systems in general, but I mention them because the Wikipedia had a decent article on L-systems.)

Consider the examples above.  You first need to specify an angle, a, and a ratio, r.  In this example, a is 45 degrees, and r is 0.5.  Start off by drawing a segment of some arbitrary length (in this case the trunk of a tree).  Then turn left by the angle a, and recurse using the length scaled by a factor of r.  When this is done, do the same recursion after turning right by the angle a.

On the left, you should see three different sized lengths, each half the size of the one before.  You should also be able to easily see the branching to the left and right by 45 degrees, and how this is done at each level.

In the middle, there are six levels, with the smallest branches only 1/32 the length of the tree trunk.  Can you guess how many levels on the right?  There are twelve, actually.  At some point, the resolution of the screen is such that recursing to deeper levels doesn’t actually make the fractal look any different.

What Nick is interested in is the following question.  Given an angle a, what is the ratio r such that all the branches of the tree just touch?  In the example below with a being 45 degrees, the leaves are just touching — increasing the ratio r would make them start to overlap.

What is r?  It turns out that there’s quite a bit of trigonometry involved to find the precise r given an angle a, but it’s not really necessary to go into all those details.  It’s just enough to know that Nick was able to work it out.

But what Nick is really interested in is just the canopies of these trees — in other words, just the outermost leaves, without the trunk or any of the branches.

Right now, he’s experimenting with creating movies which show the canopies changing as the angle changes — sometimes the ratio is fixed, other times it’s changing, too.

Two observations are worth making.  First, this was a real team effort!  Nick had done the programming and set up quite a bit of the math, and with the aid of Mathematica, I was able to help verify conjectures and get the expressions into a useable form.  We each had our own expertise, and so were each able to contribute in our own way to solving the problem.

Second, Nick is using mathematics to aid in the design process.  My first attempts to create symmetric curves using the algorithm for the Koch snowflake were fairly random.  But now that I’ve worked out the mathematics of what’s going on, I can design images with various interesting properties.

Likewise, Nick has in mind a very particular animation for his movies — using the just-touching canopies — and is using mathematics in a significant way to facilitate the design process.  Sure, you can let the computer crunch numbers until you get a good enough approximation — but the formula we derived gives the exact ratio needed for a given angle.  This is truly mathematical art.

I’ll keep you updated as more progress is made on these projects.  I’ll end with my favorite image of the week.  The idea came from Nick, but I added my own spin.  It’s actually canopies from many different trees, all superimposed on each other.  Enjoy!

## Color II: Opacity and Josef Albers

Remember from last week we were discussing the following image:

What colors are the squares?  Recall that when we allowed one or both squares to be transparent to some degree, there were many possible answers to this question.  Last week, we found out all possible color/opacity combinations for the purple square alone.

First, we’ll examine the case that the pink square is transparent and on top of the purple square.  Whether the purple square is transparent actually doesn’t matter, so we’ll be perfectly fine if we assume the purple square has RGB values $(0.6,0.5,1)$ with opacity 1.

To begin, we need to establish the apparent color of the pink square.  If I load this image into Photoshop and use the eyedropper tool, I get integer RGB values of  $(229, 51, 255).$  Dividing these by 255 to convert to values between 0 and 1, I get $(0.898039, 0.2, 1).$  I actually used RGB values of $(0.9,0.2,1)$ to create the image, so the eyedropper tool did its job….

Now let’s call the color of the pink square $(R,G,B),$ and the opacity $a.$  Recall the formula from last week for the result of looking through a transparent color:

$a\, C_1+(1-a)\,C_2.$

In our case, $C_1$ is the color of the pink square, and $C_2$ is the color of the purple square.  So we get the equation

$(0.9,0.2,1)=a\,(R,G,B)+(1-a)\,(0.6,0.5,1).$

As before, we need to break this down into three separate equations, one for each component.  For exactly the same reasons as last week, we must have $B=1$ (go back and reread this argument if you forgot).  The equations for the Red and Green components are

$0.9=a\,R+(1-a)\,0.6,\qquad 0.2=a\,G+(1-a)\,0.5,$

which may be rearranged to yield

$R=0.6+\dfrac{0.3}a,\qquad G=0.5-\dfrac{0.3}a.$

Since color values lie between 0 and 1, we see from the Red equation that we must have

$0\le\dfrac{0.3}a\le0.4.$

Note that when this is true, the Green value also lies between 0 and 1, so this is all we need to check.  A little simplification shows that this implies $0.75\le a,$ so the pink square can be transparent as long as

$0.75\le a\le1.$

We can then use the formulas above to fing the Red and Green values (remembering that Blue is always 1).  Below are the possibilities in RG space:

The point X corresponds to the value $a=1,$ while the point Y corresponds to $a=0.75.$  Note that while the possible points in RG space lie on a line segment (it is easy to see from the above formulas that $R+G=1.1$), the points on the line segment do not vary linearly with $a$ since the $a$ occurs in the denominator in the above formulas.

So now we’ve looked at all the possibilities when the pink square is transparent and on top of the purple square.  What if the purple square is transparent and on top of the pink square?

We first note that half the work is already done, since we worked out the possibilities for a transparent purple square last week.  Here is what we obtained, where again the opacity of the purple square is denoted by $a$:

$R=\dfrac{a-0.4}a,\quad G=\dfrac{a-0.5}a,\quad B=1.$

This corresponds to the color $C_1$ in the formula for opacity.  Now let $(R,G,B)$ denote the color of the pink square underneath, which will be $C_2.$  Using the opacity formula, we obtain the equation

$(0.9,0.2,1)=a\,\left(\dfrac{a-0.4}a,\dfrac{a-0.5}a,1\right)+(1-a)\,(R,G,B).$

This may look a little complicated, but it turns out we only need to look at the Red component.  Looking at the Red color value, we get

$0.9=a\left(\dfrac{a-0.4}a\right)+(1-a)\,R,$

which after multiplying out and rearranging results in

$R=\dfrac{1.3-a}{1-a}.$

Can you see any problem with this formula for $R?$  Since the opacity must be between 0 and 1 — in other words, $0\le a\le1$ — the numerator of this expression will always be greater than the denominator.  This means that the Red color value would have to be greater than 1, which we know is not possible!

Our conclusion?  It is not possible that the two squares can be obtained by a pinkish square beneath a transparent purple square.  Essentially, the pink is “too red.”  In order to make the pink show through the purple, the opacity of the purple would have to be too close to 0, which would then mean that we’re not seeing enough blue.

In general, this is not easy to just see by quickly glancing at an image.  But if we use the formula for opacity and are careful with our calculations, we can prove that certain color/transparency combinations are impossible.

And what about a more complex figure?

Well, there are four different squares to consider, and several different possible layerings.  But it’s even more complicated than that.

What you’re seeing is an image on your color monitor or phone, which is on my website.  I got the image from the Wikipedia commons.  Someone uploaded a digital file of the image, which was either taken of the original piece, or digitized from a photograph of the piece.  Which might have been from a book, published long enough after Albers finished the piece that the photo was actually of a faded original.

So what we’re actually seeing is only an approximation to Albers’ original painting.  To make the analysis more realistic, we’d have to assume that the apparent color we’re seeing is within a certain tolerance of the original.  Meaning each color doesn’t have just one value, but a range of possible values.

We won’t go into this more complicated issue today.  But I hope you now appreciate that an image of just a few squares may be much more intriguing than you might originally think!