Cheesegraters and crystals

Earlier this week, Stephen Hackett wrote a nice article on the design of the new Mac Pro’s grill and how it’s related to older and simpler Apple grill designs. It led me to Apple’s page on the design of the Pro and this language:

The lattice pattern on Mac Pro is based on a naturally occurring phenomenon in molecular crystal structures. A network of three-dimensional interlocking hemispheres, it increases the surface area, optimizing airflow and structural rigidity.

… The result is a lightweight lattice pattern that maximizes airflow while creating an extremely rigid structure.

This isn’t just marketing blather. The hole are a negative-space representation of a common atomic arrangement in metallic crystals, something that most engineers learn about in their introductory materials science class.

Atoms are hard to see, but crystal structures bear a geometric relationship to the packing of spheres, which are easy to see. We start with a layer of spheres and then set another layer on top of it, with the balls of the second layer fitting into valleys formed by the first layer.

Layers 1 and 2

Two things about these drawings:

We can now set a third layer on top of the second, but there are two ways to do it. In one (on the left), the balls of the third layer are directly above those of the first. In the other (right), the balls of the third layer are set in the openings that run through the first two layers.

Two arrangements of Layer 3

The left method is called the “hexagonal close packed” (hcp) structure, and the right is called “face-centered cubic” (fcc).

The hcp structure is fairly easy to visualize. Image a layer of seven balls arranged in a hexagon, then a layer of three, then a layer of seven again.

Hexagonal close packed

In materials science books, the hcp crystal structure, in which atoms arrange themselves like the spheres we’ve been looking at, is usually shown in an oblique view, like in the drawing at the lower right. That shows you the three layers and all the atom locations in a single image.

The fcc structure isn’t as obvious because it’s harder to visualize cubic arrangements in our layers of balls. I find it easiest to imagine four layers: three layers like those shown above and another that’s just like the green layer but placed below the blue layer.

Face centered cubic arrangement

The trick is to recognize that the faces of the cube aren’t aligned with the layers of balls. We’re looking down the diagonal of a cube, with the green balls at the farthest and nearest corners.

Face centered cubic crystal structure

The drawing on the right is the fcc crystal structure as it would commonly be shown in a materials science book.

Now we can see how the cheesegrater grill of the Mac Pro is related to crystal structures. Here’s Apple’s animation of the machining process, which gives a good 3D view of the holes.

alt : Mac Pro grill

A frame capture from the video shows how the hemispherical holes machined into the aluminum plate are arranged like the blue and red layers in our sphere-packing drawings.. The holes on the near side are like the layer of red spheres, and the holes on the far side are like the layer of blue spheres.

Holes and spheres

Now you can see why I drew the spheres of each layer slightly separated from one another. It was to match the separation of the holes on the two sides of the plate. The holes need to be separated to keep the grill from falling apart.

The other difference between the holes in the Mac Pro grill and the packing of spheres is that the holes from the two sides don’t simply touch, they intersect. Otherwise, there’d be no airflow.

So, the lattice pattern on Mac Pro really is “based on a naturally occurring phenomenon in molecular crystal structures.” I have no idea how this “maximizes airflow”—I suspect maximum airflow would come if the holes from one side were drilled straight through. But if the holes were drilled straight through it wouldn’t look as cool. Also, Stephen and I would have had nothing to write about.

One last thing, which I’m sure delights the metallurgists at Apple. Aluminum has an fcc structure, so the geometry of the grill mimics—in part, at least—the atomic arrangement of the material from which it’s made.

Listening, fast and slow

Marco Arment’s recent post, “Apple is Listening,” got me thinking about Apple’s on-and-off history of listening to its customers. Apple prides itself on figuring out what people want before they can articulate it. There’s lots of talk about “faster horses” and “skating to where the puck is going.” And there’s no question that some of Apple’s biggest successes have come from ignoring the conventional wisdom.

But sometimes people really do know what they want, and Apple’s track record in recognizing when that’s the case is spotty. I have a couple of favorite highs and lows.

Apple introduced the Watch in a September 2014 event and released it the following April. As Ben Thompson said in the wake of the introduction, the Watch was unique among Apple products in that there didn’t seem to be a story about why it existed or what it was for.1 It was just a hodgepodge of unfocused features.

Apple’s customers, though, figured out what the Watch was for right away: fitness. And remarkably, Apple listened. Development and marketing turned on a dime and went all-in on fitness. The Watch’s success came from Apple paying attention to its customers and giving them what they wanted.

My favorite example of Apple’s failure to listen is not the Mac Pro (although that’s a good one) but the Mac mini. The Mac mini was released in 2005. It was marketed as an entry level Mac for people who owned a computer but wanted a low cost way to switch—another way for Apple to take advantage of the iPod halo effect. Many of Apple’s regular customers, though, saw the mini as an inexpensive2 way to get a second Mac to use as a home server.3

Apple must have known this, but didn’t act on it for four years. It began selling the mini with OS X Server preinstalled in 2009. That continued through the salad days of the mini, with new versions released in 2010, 2011, and 2012.4

And then it stopped. There was no 2013 mini. Even worse, the 2014 version was a sealed unit. The RAM couldn’t be upgraded, and there was no option for buying one with OS X Server preinstalled. Apple apparently decided that what the mini’s customers said they wanted wasn’t what they really wanted. The 2014 mini was a big disappointment, and mini users began snapping up the 2012 versions wherever they could find them. Apple stopped development after 2014, probably because of poor sales brought on by its anti-customer redesign.

Last fall, six years after the last “good” version, Apple listened again, reintroducing the mini as a highly configurable system, with prices that range from $800 for a baseline model to $3,600 for a super tricked-out screamer.5

Unlike the Watch, Apple had a strong idea of what the mini was for when it was introduced. But it was, as it turned out, the wrong idea, and the product now has a 14-year history of Apple not listening, listening, not listening, and listening.

I don’t think any Apple enthusiasts want the company to become driven entirely by focus groups. The customer isn’t always right. But sometimes…

  1. One thing it was not for was fashion. Apple at the time was presenting itself as a nascent fashion brand, and tried to position the Watch as a competitor to Rolex, Breitling, Tag Heuer, and so on. That failed so thoroughly that the only traces of it left are the Hermès bands. 

  2. You might argue with the “inexpensive” characterization, but there’s more to expense than money. If you’re very familiar with Mac software and your other computer is a Mac, a server that runs OS X can mean a huge savings in time and frustration. 

  3. Or an out-of-home server. Macminicolo understood the value of the mini immediately and began offering colocation services for users who wanted their mini in a high bandwidth data center. 

  4. You certainly didn’t need OS X Server to use a mini as a server, but offering it preconfigured that way allowed Apple’s customers another opportunity to trade money for time. 

  5. Assuming the only screaming you need is from the main CPU, not graphics. 


Twitterrific 6 was released a couple of days ago, and by now you’ve probably read Ryan Christoffel’s article and Jason Snell’s. I’ve been a Tweetbot user for ages, but I thought it was worth giveng Twitterrific a try. I can’t say yet that I’ll switch, but I’ve been pleased with my first two days of use.

Before getting into the app itself, I’d like to thank Iconfactory for providing useful subscription tiers for trying out the app. You can install Twitterrific for free, in which case you’ll see ads at the top of the screen. Personally, I don’t think this is a good way to evaluate an app, because the presence of the ads takes away from the true app experience. For 99¢, though, you can get a month subscription, which is what I chose. This is a cheap way to get a decent length of time to decide whether it’s going to replace Tweetbot.

Subscription options

At the end of the month, I’ll decide whether to switch to the year subscription or go back to Tweetbot.1

The main reason I haven’t used Twitterrific in the past is that I was put off by its color schemes. I could never identify exactly what I didn’t like about them, but they just didn’t seem right. Now the default light theme, which is what I use almost all the time, is just about perfect, and I’ve settled on a dark theme that works well, too.

Theme and layout preferences

As Jason says in his article, you can tweak the theme by editing a plist file and putting it into the Day or Night subfolder of the Twitterrific iCloud Drive folder. Officially, this is an “unsupported” feature, but there’s a sample plist file in the Themes subfolder that you can use as a starting point and a README file with some details.

Theme files for Twitterrific

It would be nice if Iconfactory provided plists for each of the standard themes so you could pick the one closest to your taste and just change a few colors. Maybe we’ll get that in a later release.

Even without editing a theme, you have pretty good control over the way your Twitterrific screen looks. Here are the options for font size:

Font sizes

If you can’f find what you want in that list, you may need to write your own Twitter client. By the way, all of these font sizes are relative to the default size, which matches the size chosen in the Accessibility settings. You can see this if you put Twitterrific and Settings next to each other in the app carousel.

Default font size matches accessibility setting

A small but welcome feature is how Twitterrific lets you navigate the hierarchy of settings. As you can see below, the sidebar has a gear icon at the lower right. Clicking it brings up the first level of settings, most items of which lead to another level of choices.

Settings hierarchy

In most apps, after going down the hierarchy to change what you want, you have to go back up the hierarchy one step at a time before you can dismiss the settings popover. But Twitterrific gives you a Done button that allows you to bail out of settings and go back to the app at every step. I suppose this becomes less helpful with time, as once you get the settings you like you tend to stick with them, but it’s a surprisingly big time saver when you’re first starting out.

In summary, Twitterrific 6 is looking good so far. I’ll be back in a few weeks with a final verdict.

  1. There’s also a one-time payment option of $29.99 (shocking!) that doesn’t appear in the Subscriptions area of Settings. 

OmniGraffle and paths

Over the years, I’ve mentioned several times that I use OmniGraffle in ways that don’t match up with its main purpose of making org charts and similar sorts of diagrams. Here’s another one.

Let’s say there’s a suspected problem with an outdoor walkway paved with bricks, and I have been asked to look into it. One of the things I need to know before getting into the meat of the investigation is how big the walkway is. This would be easy if the walkway were a regular shape, but landscape architects usually prefer more organic shapes. My solution has three steps:

  1. Outline the walkway in OmniGraffle. I approximate the curvy boundaries with a series of short straight lines.
  2. Use AppleScript to extract the coordinates of the polygon created in Step 1.
  3. Use Python to calculate the area from the coordinates found in Step 2.

In Step 1, I import the drawing of the walkway (typically a PDF) into OmniGraffle. I put it in its own layer, and then create a layer for tracing the outline. I use the Bézier tool in this layer to click along the boundary of the drawing underneath. For accuracy in following the boundary, it helps to set the line used for the Bézier to a contrasting color with less than 100% opacity. When I’ve gone all around the boundary, I get something that looks like this:

Outline in OmniGraffle

In this drawing, to make things easier to see. I’ve made the Bézier outline thicker than I normally would, I’ve set its opacity back to 100%, and I’ve filled it with a translucent color.

Now it’s time to get the vertex coordinates of the polygon. It’s a simple AppleScript:

1:  tell application "OmniGraffle"
2:    tell layer "Outline" of canvas 1 of document 1
3:      tell first graphic
4:        get point list
5:      end tell
6:    end tell
7:  end tell

The script is called polypoints, and when I run it in Script Debugger, the results show up in one of the right-hand panes.

Polypoints script in Script Debugger

The output is a list of lists, which has, as luck would have it, exactly the same syntax in AppleScript as it does in Python. I can just copy it from Script Debugger and use it directly in an assignment statement in the Python script that calculates the area. Here is that script:

  1:  #!/usr/bin/env python
  3:  import section
  4:  import sys
  6:  # The vertex coordinates, in points, from OmniGraffle
  7:  path = [ [305.975, 189.562], [305.975, 189.562], [318.913,
  8:    194.062], [318.913, 194.062], [318.913, 194.062], [314.975,
  9:    204.188], [314.975, 204.188], [314.975, 204.188], [327.35,
 10:    209.25], [327.35, 209.25], [327.35, 209.25], [339.725,
 11:    .
 68:    .
124:    .
125:    161.438], [331.288, 161.438], [330.163, 163.688], [330.163,
126:    163.688], [330.163, 163.688], [316.663, 159.75], [316.663,
127:    159.75], [316.663, 159.75], [305.975, 189.562] ]
129:  # Flip the y-axis and scale to feet
130:  path = [ (0.2971*x, -0.2971*y) for x, y in path ]
132:  # Reset origin and determine size of bounding rectangle
133:  xmin = min(p[0] for p in path)
134:  ymin = min(p[1] for p in path)
135:  path = [ (p[0] - xmin, p[1] - ymin) for p in path ]
136:  width = max(p[0] for p in path)
137:  height = max(p[1] for p in path)
139:  # Areas
140:  fraction = section.area(path)/(width*height)
141:  print('{:>20s}: {:6,.0f}'.format('Paver area', section.area(path)))
142:  print('{:>20s}: {:6,.0f}'.format('Enclosing rectangle', width*height))
143:  print('{:>20s}: {:5.2%}'.format('Fraction', fraction))

For the sake of your sanity and mine, I’ve elided 115 lines of vertex data.

Regardless of document’s settings for units and scaling, the OmniGraffle AppleScript dictionary gives the coordinates of the polygon’s vertices in points. And the y coordinates measure down from the top of the document instead of up from the bottom. Neither of these conventions are useful to me, so Line 19 fixes both, flipping the y axis and converting the dimensions from points to feet.

How did I come up with the scaling factor of 0.2971? There are several dimensions given in the drawing. I took the longest one, noted its length in feet, measured it in points on the drawing, and divided to get the scaling factor.

Lines 22–26 find the smallest rectangle that encloses the polygon, resets the origin of the coordinates to the lower left corner of that rectangle, and calculates its height and width.

Line 30 uses the area function of my section properties module to report the area of the polygon. The other lines near Line 30 calculate some ancillary values that can be helpful if I need to do more than just get the area.

For instance, if I want to test some of the bricks, I can get a random sample by generating random values for x and y within the bounding rectangle and retaining only those that are inside the polygon. How do I know if a point is inside the polygon? Use the contains_point function from the matplotlib.path module.

If you’re the first one to read this far without bailing, I have a reward for you that’s sort of tangential to OmniGraffle. Brent Simmons, of NetNewsWire fame and currently of the Omni Group, sent me a promo code for OmniFocus. I’m not organized enough to use OmniFocus, but I bet some of you are and have just never given it a try. You may be especially interested now that it’s running on the web in addition to all your Apple devices.

Just be the first person to send me an email (drdrang at leancrew dot com) asking for it, and I’ll send you the code along with all the terms and conditions. The promo code expires on June 26 and works only in the US App Store. It gets you a year of OmniFocus Pro for iOS, OmniFocus Pro for Mac, and OmniFocus for the Web. You can learn about Omni’s new optional subscription service here.

Don’t expect a reply from me right away. I have a busy Monday and won’t be checking my alter-ego email address until later in the day. If you do end up winning, be sure to send thanks to Brent.