Terminal Silhouettes: Redrawn ORD with Concourse L Stinger

ORD

ORD.svg

Chicago O’Hare was one of the first terminal silhouettes I drew. While I generally like how it turned out, I’ve learned a lot of techniques from the dozens of terminals I’ve drawn since then. For a while, I’ve wanted to redraw ORD from scratch and try to recreate a better version of it.

Earlier this year, ORD opened an expansion to Terminal 3/Concourse L, adding another five gates (L20–L24). I’d watched its construction progress from the windows of the old Concourse L, and first got to walk through it in April.

2018-04-27 16.51.53

With this extra expansion, my terminal silhouette was now out of date. With CLT (which I also recently updated for a concourse expansion) I simply edited the drawing; however, with ORD, I decided to use this as my opportunity to redraw the silhouette from scratch.

ORD Diff

I learned a few things from my new drawing.

First, I’d always assumed that the entrances to Terminals 1, 2, and 3 (labeled below) formed half of a regular hexagon around the passenger drop-off/pick-up loops, which would mean that the terminals had 120° angles between them. However, T1 and T2 formed a 115° angle, and T2 and T3 were only at 110°. This also means that despite my prior assumptions, concourses B and C are not quite parallel with concourses F, G, and H.

ORD Terminals and Concourses

Second, I was able to confirm that the two Y-shaped concourses (E/F in Terminal 2, and H/K in Terminal 3) were basically identical in size, other than that the arms of H/K were longer. I was actually able to copy and paste E/F to create H/K, with relatively minimal modifications required.

I still think that O’Hare is one of my favorite terminal shapes. The layout has a lot of instances of symmetry while still having each terminal manage to be completely unique, and it manages to fit a lot of gates in a relatively small area in a way that’s entirely pleasing to my eyes. I had a lot of fun recreating this silhouette.

Terminal Silhouettes: Updated CLT with Concourse A Expansion

CLT

CLT.svg

Charlotte (CLT) had been building an expansion onto terminal A for a while. Nonetheless, I was pretty surprised when I flew through CLT on 18 July that I’d managed to unintentionally book a flight on the day that it opened.

The new concourse forks off from the existing Concourse A where the long moving sidewalk hallway used to be:

CLT-a-extension.png
Existing airport terminal in gray, new concourse A expansion in magenta

Unfortunately, adding the new expansion has made CLT look slightly less “like a reindeer,” as one of my friends noted about the original silhouette.

https://www.pbogard.com/projects/terminal-silhouettes

Terminal Silhouettes: LBB

LBB

LBB.svg

Lubbock was an interesting airport; it appears to be curved, but it’s actually just a bunch of straight lines with shallow angles. The main curve features fifteen segments (separated by concrete ribs) over ninety degrees, so each one occupied only a six-degree slice of the curve.

Additionally, while I normally leave out awnings, LBB’s awning was really part of the structure, and connected by the concrete ribs, giving the terminal such a signature look that I really had to include it.

https://www.pbogard.com/projects/terminal-silhouettes

 

State Abbreviations Graph

In a recent chat that I participated in, we were discussing US two-letter state abbreviations that were one letter off of each other (e.g., NY and NJ).

After that discussion, I was curious about whether it would be possible to step from any state abbreviation to any other by changing one letter at a time, using only valid states along the way. My first step was to determine if there were any state abbreviations which didn’t share a first or last letter with any other states, so I wrote a simple Ruby script to test that.

state_codes = %w(AL AK AZ AR CA CO CT DE FL GA HI ID IL IN IA KS KY LA ME MD MA MI MN MS MO MT NE NV NH NJ NM NY NC ND OH OK OR PA RI SC SD TN TX UT VT VA WA WV WI WY)
state_codes.sort!
one_letter_changes = Hash.new()
state_codes.each do |sc|
  one_letter_changes[sc] = state_codes.select{|s| sc != s && (sc[0] == s[0] || sc[1] == s[1])}
  puts "#{sc}: #{one_letter_changes[sc].join(", ")}"
end
Matching States

So every state had at least one other state it could go to. Texas (TX) had the fewest, with only Tennessee (TN); Massachusetts (MA) had the most, as quite a few state codes start with M or end with A.

Now I needed to find out if all the states would connect to each other, or if there would be several distinct “neighborhoods” of states. I decided to do this visually by creating a graph, using the output of my script to draw the connections:

State One Letter Changes
Graph with US state abbreviations as the vertices, green lines connecting state abbreviations with the same first letter, and blue lines connecting state abbreviations with the same second letter

Based on this graph, it is possible for any state abbreviation to change to any other state abbreviation!

I was also curious about the number of steps needed to go between any pair of state abbreviations, so I wrote a path distance algorithm based on Dijkstra’s algorithm (but with each path having equal weight) to find the shortest number of hops between any pair:

state_codes = %w(AL AK AZ AR CA CO CT DE FL GA HI ID IL IN IA KS KY LA ME MD MA MI MN MS MO MT NE NV NH NJ NM NY NC ND OH OK OR PA RI SC SD TN TX UT VT VA WA WV WI WY)
state_codes.sort!
one_letter_changes = Hash.new()
state_codes.each do |sc|
  one_letter_changes[sc] = state_codes.select{|s| sc != s && (sc[0] == s[0] || sc[1] == s[1])}
end

def path_distance(graph, source)
  vertexes = graph.keys
  return nil unless vertexes.include?(source)
  
  distance = Hash.new()
  previous_vertex = Hash.new()
  arbitrarily_large_distance = vertexes.length
  unvisited_vertices = Array.new

  vertexes.each do |v|
    distance[v] = arbitrarily_large_distance
    previous_vertex[v] = nil
    unvisited_vertices.push(v)
  end
  distance = 0;

  while(unvisited_vertices.any?)
    min_distance_vertex = unvisited_vertices.min_by{|v| distance[v]}
    
    graph[min_distance_vertex].each do |neighbor|
      alt = distance[min_distance_vertex] + 1
      if alt < distance[neighbor]
        distance[neighbor] = alt
        previous_vertex[neighbor] = min_distance_vertex
      end
    end
    unvisited_vertices -= [min_distance_vertex]
  end

  return distance

end

state_codes.each do |code|
  values = path_distance(one_letter_changes, code).sort_by{|k,v| k}.reject{|k,v| k > code}.map{|d| d[1]}
  puts "#{code}  #{values.join("  ")}"
end
puts "   #{state_codes.join(" ")}"
State to State

Based on the results, the highest number of hops is 6 – so every state abbreviation can be changed into any other state abbreviation in at most six steps!