Plan a Light

How Lighthouses Work

Chapter 9 ยท Plan a Light

This is the capstone, so for once we build instead of learn. Imagine you have been asked to put a light on a headland. Nobody has told you how tall to make the tower, how bright the lamp must be, or what rhythm it should flash, and each of those answers comes from a different part of How Lighthouses Work 1 to 8: the horizon and the inverse square law, the lamps and lenses, the flash characters, the rock and the weather. In this chapter we turn those pieces into one small Python range calculator, use it to meet a written brief, choose a characteristic that cannot be confused with the lights next door, read a chart label the way a mariner does, and finish by putting the three Stevenson rock lights side by side.

What was run, and what to trust
Every Python snippet in this chapter and in the three exercise solutions was run, and the output in the comments is what Python printed. The headland, the brief, the ship's eye height, the tower and ground heights, the 1 s flashes and the rule that two lights are confusable when their periods are within 3 s are my inventions and are labelled where they appear: the plan is a worked example, not a real design and not a navigation aid. The figures for the three real lights come from the infoboxes of the English Wikipedia pages for the Bell Rock Lighthouse, Skerryvore and Muckle Flugga Lighthouse, which I read directly for this chapter: focal heights of 28 m, 46 m and 66 m, listed ranges of 18, 23 and 22 nautical miles, and, for the Bell Rock only, the characteristic "Fl. W 5s 28m 18M" with a flash of 0.1 s and an eclipse of 4.9 s, a hyper-radial Fresnel lens and an intensity of 1,900,000 candela. The characteristics of Skerryvore and Muckle Flugga (Fl W 10s and Fl(2) W 20s), the automation years and the first-lit years are carried over from How Lighthouses Work 6 and 8 and were not looked up again. The chart-label convention comes from the Wikipedia page on light characteristics. All sums, ratios and conversions are my arithmetic. Where the sources disagree, the chapter says so.

The Brief

A planner starts with a statement of what the light is for. Mine is invented: a headland with a cliff top 20 m above the sea, a shipping lane offshore, and ships whose bridges are 8 m above the water. The light must be seen from 15 nautical miles in the standard weather of How Lighthouses Work 1 (meteorological visibility 10 nautical miles), and still from 6 nautical miles when the visibility falls to 2 nautical miles. Both figures are assumptions chosen to make the example work; a real brief would come from the authority and from the traffic.

Every decision in the brief answers to one of the earlier chapters, and the order matters, because the limits are independent: the horizon sets one, the brightness another, and what a sailor sees is the smaller of the two.

DecisionThe questionThe toolWhere it came from
Height of the lightHow far does the horizon allow it to be seen?geographic range, 2.084 (โˆšH + โˆšh) nautical milesHow Lighthouses Work 1
IntensityHow far does the brightness carry in haze?Allard's law, solved by bisectionHow Lighthouses Work 1 and 3
OpticsHow do I turn a small flame or lamp into a bright beam?a Fresnel lens of a chosen orderHow Lighthouses Work 4
CharacteristicHow will a sailor tell it from the next light?Fl, Oc, Iso and group patternsHow Lighthouses Work 5
Site and structureCan the tower be built, and who builds it?cliff top or rock; tide-limited workingHow Lighthouses Work 6 and 7
FogWhat happens when the light cannot be seen?horn, bell, raconHow Lighthouses Work 8

A Range Calculator

The calculator is three functions. The first is the geographic range of How Lighthouses Work 1, with the light and the eye both contributing a horizon. The second finds the luminous range by bisection: it keeps halving an interval until the illuminance given by Allard's law falls to 0.2 microlux, and it takes the visibility as the distance at which 5% of the light survives, as that chapter did. The third returns the smaller of the two. The table it prints crosses three heights with two lamps, 100,000 cd and 1,000,000 cd (both assumed), for an 8 m eye.

# A range calculator for a proposed light: geographic range, luminous range and what is seen. import math NM = 1852.0 # metres in a nautical mile KM_PER_SQRT_M = 3.86 # horizon constant with standard refraction THRESHOLD_LX = 2e-7 # 0.2 microlux, the nominal-range convention def geographic_range_nm(light_m, eye_m): return KM_PER_SQRT_M * (math.sqrt(light_m) + math.sqrt(eye_m)) / (NM / 1000) def luminous_range_nm(intensity_cd, visibility_nm): t = 0.05 ** (1 / visibility_nm) # transmissivity per nautical mile lo, hi = 0.01, 200.0 for _ in range(100): mid = (lo + hi) / 2 lux = intensity_cd * t ** mid / (mid * NM) ** 2 if lux > THRESHOLD_LX: lo = mid else: hi = mid return (lo + hi) / 2 def seen_range_nm(light_m, eye_m, intensity_cd, visibility_nm): return min(geographic_range_nm(light_m, eye_m), luminous_range_nm(intensity_cd, visibility_nm)) EYE_M = 8 # assumed bridge height of the ships the light is for print("height | intensity | nominal | geographic | seen (10 nm) | seen (2 nm)") for height in (20, 40, 60): for cd in (100_000, 1_000_000): nominal = luminous_range_nm(cd, 10) geo = geographic_range_nm(height, EYE_M) print(height, "m |", cd, "cd |", round(nominal, 1), "nm |", round(geo, 1), "nm |", round(seen_range_nm(height, EYE_M, cd, 10), 1), "nm |", round(seen_range_nm(height, EYE_M, cd, 2), 1), "nm") # height | intensity | nominal | geographic | seen (10 nm) | seen (2 nm) # 20 m | 100000 cd | 19.8 nm | 15.2 nm | 15.2 nm | 5.6 nm # 20 m | 1000000 cd | 25.7 nm | 15.2 nm | 15.2 nm | 6.9 nm # 40 m | 100000 cd | 19.8 nm | 19.1 nm | 19.1 nm | 5.6 nm # 40 m | 1000000 cd | 25.7 nm | 19.1 nm | 19.1 nm | 6.9 nm # 60 m | 100000 cd | 19.8 nm | 22.0 nm | 19.8 nm | 5.6 nm # 60 m | 1000000 cd | 25.7 nm | 22.0 nm | 22.0 nm | 6.9 nm

Three things stand out. At 20 m a lamp ten times brighter changes nothing in clear weather: both lamps are cut off by the horizon at 15.2 nm. At 60 m the dimmer lamp is the limit (19.8 nm against a horizon of 22.0 nm), so there more intensity helps. And in poor visibility the height makes no difference at all: the 2 nm column reads 5.6 nm for the 100,000 cd lamp and 6.9 nm for the 1,000,000 cd lamp at every height, because the air, not the horizon, is the limit. Ten times the intensity gave only about 1.2 times the range (6.9 divided by 5.6, from the rounded figures), which is the inverse square law at work again.

LightClear weather (10 nm)Poor weather (2 nm)
Low and dim (20 m, 100,000 cd)15.2 nm, the horizon decides5.6 nm, the brightness decides
Low and bright (20 m, 1,000,000 cd)15.2 nm, the horizon decides6.9 nm, the brightness decides
High and dim (60 m, 100,000 cd)19.8 nm, the brightness decides5.6 nm, the brightness decides
High and bright (60 m, 1,000,000 cd)22.0 nm, the horizon decides6.9 nm, the brightness decides

Meeting the Brief

Now run the calculator backwards. Given a required range, the focal height that just reaches it follows from solving the geographic formula for H, and the intensity that just reaches it can be found by searching on the luminous-range function itself; the search below halves the interval on a logarithmic scale, because the answer could be anywhere from a candle to millions of candela. The code does the clear-weather case and the poor-weather case separately, keeps the larger intensity, and then tests a tower of my choosing, 12 m on the 20 m cliff, against the horizon.

# Solve a brief: the lowest focal height and the lowest intensity that meet a required range. import math NM = 1852.0 NM_PER_SQRT_M = 3.86 / (NM / 1000) # about 2.084 def geographic_range_nm(light_m, eye_m): return NM_PER_SQRT_M * (math.sqrt(light_m) + math.sqrt(eye_m)) def luminous_range_nm(intensity_cd, visibility_nm): t = 0.05 ** (1 / visibility_nm) lo, hi = 0.01, 200.0 for _ in range(100): mid = (lo + hi) / 2 if intensity_cd * t ** mid / (mid * NM) ** 2 > 2e-7: lo = mid else: hi = mid return (lo + hi) / 2 def height_needed_m(range_nm, eye_m): return (range_nm / NM_PER_SQRT_M - math.sqrt(eye_m)) ** 2 def intensity_needed_cd(range_nm, visibility_nm): lo, hi = 1.0, 1e9 for _ in range(200): mid = math.sqrt(lo * hi) # halve the search on a log scale if luminous_range_nm(mid, visibility_nm) < range_nm: lo = mid else: hi = mid return hi CLEAR_NM, POOR_NM, EYE_M = 15, 6, 8 # assumed brief: 15 nm in 10 nm visibility, 6 nm in 2 nm print("focal height for a", CLEAR_NM, "nm horizon:", round(height_needed_m(CLEAR_NM, EYE_M), 1), "m") cd_clear = intensity_needed_cd(CLEAR_NM, 10) cd_poor = intensity_needed_cd(POOR_NM, 2) print("intensity for", CLEAR_NM, "nm at 10 nm visibility:", round(cd_clear), "cd") print("intensity for", POOR_NM, "nm at 2 nm visibility:", round(cd_poor), "cd") need = max(cd_clear, cd_poor) print("the brief needs at least", round(need), "cd; the clear-weather case decides:", cd_clear > cd_poor) GROUND_M, TOWER_M = 20, 12 # assumed: cliff-top ground level and tower height focal = GROUND_M + TOWER_M geo = geographic_range_nm(focal, EYE_M) print("focal height", focal, "m gives", round(geo, 1), "nm; margin over the brief:", round(geo - CLEAR_NM, 1), "nm") for factor in (1, 2, 5): cd = round(need * factor) print(factor, "x:", cd, "cd -> nominal", round(luminous_range_nm(cd, 10), 1), "nm; at 2 nm visibility", round(luminous_range_nm(cd, 2), 1), "nm") # focal height for a 15 nm horizon: 19.1 m # intensity for 15 nm at 10 nm visibility: 13805 cd # intensity for 6 nm at 2 nm visibility: 197562 cd # the brief needs at least 197562 cd; the clear-weather case decides: False # focal height 32 m gives 17.7 nm; margin over the brief: 2.7 nm # 1 x: 197562 cd -> nominal 21.5 nm; at 2 nm visibility 6.0 nm # 2 x: 395125 cd -> nominal 23.3 nm; at 2 nm visibility 6.4 nm # 5 x: 987812 cd -> nominal 25.7 nm; at 2 nm visibility 6.9 nm

The horizon needs a focal height of only 19.1 m for 15 nm, and the 15 nm brightness needs only 13,805 cd. The poor-weather requirement is the hard one: 6 nm in 2 nm visibility needs 197,562 cd, about fourteen times as much (by my arithmetic from the printed figures). The line "the clear-weather case decides: False" says exactly that, and it is the lesson of the whole capstone: a lamp is sized for the bad night, a tower is sized for the good one. The 32 m focal height (20 m of cliff plus 12 m of tower) gives 17.7 nm, a margin of 2.7 nm. Doubling the minimum intensity to 395,125 cd lifts the nominal range to 23.3 nm but the poor-weather range only from 6.0 to 6.4 nm, and five times the minimum reaches 6.9 nm, so the extra lamp buys very little where it is needed. I take a round 400,000 cd, about twice the minimum and roughly a fifth of the Bell Rock's 1,900,000 cd (my arithmetic). A lens of the kind in How Lighthouses Work 4 would be what turns a lamp into that candlepower; the plan does not choose an order, and the sizes of lens in that chapter's model were illustrations, not measurements.

Choosing a Characteristic

A sailor identifies a light by its rhythm, so a new light must not look like its neighbours. For the example I place the headland between three lights with the characteristics of the Bell Rock, Skerryvore and Muckle Flugga (Fl W 5s, Fl W 10s and Fl(2) W 20s). This is an invented neighbourhood: the real lights are nowhere near each other. The code tests six candidate characteristics against two things: the rules for flashing lights quoted in How Lighthouses Work 5 (a single flash has a period of 2 to 15 s with darkness at least three times the flash; a group of two has a period of at most 20 s and a group of three or more at most 30 s), and a confusion test that is entirely my own rule: two lights are confusable if they have the same class and the same number of flashes and their periods are within 3 s of each other. The source gives no such number; it is a simple way to make the idea concrete.

# Pick a characteristic that no neighbour already uses, and check it against the flash rules. NEIGHBOURS = {"Fl W 5s": ("Fl", 1, 5), "Fl W 10s": ("Fl", 1, 10), "Fl(2) W 20s": ("Fl", 2, 20)} # class, flashes, period CANDIDATES = {"Fl W 5s": ("Fl", 1, 5), "Fl W 12s": ("Fl", 1, 12), "Fl(2) W 10s": ("Fl", 2, 10), "Fl(3) W 15s": ("Fl", 3, 15), "Fl(2) W 20s": ("Fl", 2, 20), "Iso W 4s": ("Iso", 1, 4)} FLASH_S, GAP_S = 1, 1 # assumed: 1 s flashes with 1 s gaps inside a group def passes_rules(cls, n, period): if cls == "Iso": return True if n == 1: return 2 <= period <= 15 and period - FLASH_S >= 3 * FLASH_S # single flash: darkness at least 3 times the flash limit = 20 if n == 2 else 30 return period <= limit and period > n * FLASH_S + (n - 1) * GAP_S # group: period limit, room for a final dark def confusable(a, b): return a[0] == b[0] and a[1] == b[1] and abs(a[2] - b[2]) < 3 # same class and count, periods within 3 s (my rule) def light_share(cls, n, period): return 0.5 if cls == "Iso" else n * FLASH_S / period for name, c in CANDIDATES.items(): clashes = [nb for nb, v in NEIGHBOURS.items() if confusable(c, v)] verdict = "ok" if passes_rules(*c) and not clashes else "reject" print(name, "| rules:", passes_rules(*c), "| clashes with:", clashes or "none", "| lit", round(100 * light_share(*c)), "% ->", verdict) # Fl W 5s | rules: True | clashes with: ['Fl W 5s'] | lit 20 % -> reject # Fl W 12s | rules: True | clashes with: ['Fl W 10s'] | lit 8 % -> reject # Fl(2) W 10s | rules: True | clashes with: none | lit 20 % -> ok # Fl(3) W 15s | rules: True | clashes with: none | lit 20 % -> ok # Fl(2) W 20s | rules: True | clashes with: ['Fl(2) W 20s'] | lit 10 % -> reject # Iso W 4s | rules: True | clashes with: none | lit 50 % -> ok

Fl W 5s is the Bell Rock's own character and is rejected; Fl W 12s is within 3 s of Fl W 10s; Fl(2) W 20s is identical to Muckle Flugga's. That leaves Fl(2) W 10s, Fl(3) W 15s and Iso W 4s. All three would do; I choose Fl(3) W 15s, three flashes in 15 s, because a group of three is easy for a tired watchkeeper to count and no neighbour shows one. It is lit 20% of the time (three 1 s flashes in 15 s), the same share as the Fl(2) W 10s option, and its group of three needs a period of at most 30 s, which it meets easily.

Reading a Chart

The finished design appears on a chart as one line of text. The page on light characteristics gives the convention: the class and group, the colour, the period, the height of the light above the chart datum (usually based on high water), and a range in nautical miles written with an M. Its worked example, "Gp Oc(3) W 10s 15m 10M", is described as a group occulting white light with a period of 10 s, 15 m high, whose nominal range is 10 nautical miles. The page is not consistent about the range: in the list it calls the range "the range in which the light is visible", and in the example it calls it the nominal range. As How Lighthouses Work 1 explained, the nominal range ignores the horizon, so I follow the worked example. Our design therefore reads "Fl(3) W 15s 32m 23M": 32 m is the focal height, and 23 is the 23.3 nm of the 395,125 cd run, rounded.

The code below parses a label with a regular expression, works out how far a 5 m eye can see the light, and says whether the horizon or the brightness is the limit. It then does the reverse: given a list of the times at which flashes began, it finds the long gap in the pattern and counts the flashes between two long gaps.

# Read a chart label, then identify a light from stopwatch readings. import math import re NM_PER_SQRT_M = 2.084 def parse(label): pattern = r"(?P<cls>Fl|LFl|Iso|Oc)(?:\((?P<n>\d+)\))?\s+(?P<col>[WRG])\s+(?P<period>\d+)s\s+(?P<h>\d+)m\s+(?P<rng>\d+)M$" d = re.match(pattern, label).groupdict() return d["cls"], int(d["n"] or 1), d["col"], int(d["period"]), int(d["h"]), int(d["rng"]) for label in ("Fl W 5s 28m 18M", "Fl W 10s 46m 23M", "Fl(2) W 20s 66m 22M", "Fl(3) W 15s 32m 23M"): cls, n, col, period, h, rng = parse(label) geo = NM_PER_SQRT_M * (math.sqrt(h) + math.sqrt(5)) limit = "horizon" if geo < rng else "brightness" print(label, "| flashes", n, "| period", period, "s | 5 m eye sees to", round(geo, 1), "nm | limited by", limit) def identify(starts): gaps = [round(b - a, 1) for a, b in zip(starts, starts[1:])] long_gap = max(gaps) first = gaps.index(long_gap) second = gaps.index(long_gap, first + 1) n = second - first # flashes between two long gaps period = round(sum(gaps[first:second]), 1) return n, period watch = [3.0, 5.0, 7.0, 18.0, 20.0, 22.0, 33.0, 35.0, 37.0, 48.0] # flash start times in seconds print("gaps:", [round(b - a, 1) for a, b in zip(watch, watch[1:])]) print("flashes per group and period:", identify(watch)) # Fl W 5s 28m 18M | flashes 1 | period 5 s | 5 m eye sees to 15.7 nm | limited by horizon # Fl W 10s 46m 23M | flashes 1 | period 10 s | 5 m eye sees to 18.8 nm | limited by horizon # Fl(2) W 20s 66m 22M | flashes 2 | period 20 s | 5 m eye sees to 21.6 nm | limited by horizon # Fl(3) W 15s 32m 23M | flashes 3 | period 15 s | 5 m eye sees to 16.4 nm | limited by horizon # gaps: [2.0, 2.0, 11.0, 2.0, 2.0, 11.0, 2.0, 2.0, 11.0] # flashes per group and period: (3, 15.0)

For a 5 m eye the first three lights are limited by the horizon, at 15.7, 18.8 and 21.6 nm, against printed ranges of 18, 23 and 22 nm, which is the finding of How Lighthouses Work 6 again. Our own design is also limited by the horizon (16.4 nm for a 5 m eye, against 23 nm printed), which is a reminder that a bigger number on the chart is not a longer view. The stopwatch readings contain gaps of 2 s, 2 s and 11 s repeated, so the pattern is three flashes with a period of 2 + 2 + 11 = 15 s, which is the character we chose. This simple version looks only at when flashes begin, so it cannot tell an isophase light from an occulting one, or a short flash from a long one; a mariner would also note how long each flash lasts.

Three Scottish Lights Compared

Finally, put the planning tool to work on real lights. The data are the focal heights and listed ranges read from the pages, the characteristics from How Lighthouses Work 6, and the years from How Lighthouses Work 6 and 8. For each light the code finds the horizon for a 5 m eye, compares it with the listed range, works out how high an eye would have to be for the listed range to be the horizon, and counts the flashes an hour.

# Compare three Scottish rock lights, using the figures from the earlier chapters. import math NM_PER_SQRT_M = 2.084 LIGHTS = ( # (name, focal height m, listed range nm, characteristic, period s, flashes per period, first lit, automated) ("Bell Rock", 28, 18, "Fl W 5s", 5, 1, 1811, 1988), ("Skerryvore", 46, 23, "Fl W 10s", 10, 1, 1844, 1994), ("Muckle Flugga", 66, 22, "Fl(2) W 20s", 20, 2, 1858, 1995), ) print("name | geographic (5 m eye) | listed | listed/geographic | eye needed | flashes per hour | years to automation") for name, h, rng, ch, period, n, lit, auto in LIGHTS: geo = NM_PER_SQRT_M * (math.sqrt(h) + math.sqrt(5)) eye = (rng / NM_PER_SQRT_M - math.sqrt(h)) ** 2 print(name, "|", round(geo, 1), "nm |", rng, "nm |", round(rng / geo, 2), "|", round(eye, 1), "m |", round(3600 / period * n), "|", auto - lit) tall = max(LIGHTS, key=lambda x: x[1]) low = min(LIGHTS, key=lambda x: x[1]) print("height ratio", tall[0], "to", low[0], ":", round(tall[1] / low[1], 2)) print("geographic range ratio, 5 m eye:", round((math.sqrt(tall[1]) + math.sqrt(5)) / (math.sqrt(low[1]) + math.sqrt(5)), 2)) print("Bell Rock flash of 0.1 s in 5 s: lit", round(100 * 0.1 / 5, 1), "% of the time") print("a 0.1 s flash at 5 s per turn matches a beam", round(0.1 / 5 * 360, 1), "degrees wide") print("model hyper-radial beam of 0.86 degrees at 5 s per turn lasts", round(0.86 / 360 * 5, 3), "s") # name | geographic (5 m eye) | listed | listed/geographic | eye needed | flashes per hour | years to automation # Bell Rock | 15.7 nm | 18 nm | 1.15 | 11.2 m | 720 | 177 # Skerryvore | 18.8 nm | 23 nm | 1.22 | 18.1 m | 360 | 150 # Muckle Flugga | 21.6 nm | 22 nm | 1.02 | 5.9 m | 360 | 137 # height ratio Muckle Flugga to Bell Rock : 2.36 # geographic range ratio, 5 m eye: 1.38 # Bell Rock flash of 0.1 s in 5 s: lit 2.0 % of the time # a 0.1 s flash at 5 s per turn matches a beam 7.2 degrees wide # model hyper-radial beam of 0.86 degrees at 5 s per turn lasts 0.012 s
Bell RockSkerryvoreMuckle Flugga
Focal height28 m46 m66 m
CharacteristicFl W 5sFl W 10sFl(2) W 20s
Listed range18 nm23 nm22 nm
Horizon, 5 m eye15.7 nm18.8 nm21.6 nm
Listed range / horizon1.151.221.02
Flashes an hour720360360
First lit to automation177 years150 years137 years

Muckle Flugga is the only one whose listed range matches the geometry (a ratio of 1.02, an eye of 5.9 m), which suggests that its range is a horizon figure for a low boat, while the Bell Rock and Skerryvore ranges are larger than any such horizon and would have to be nominal ranges or assume a high eye. I cannot tell which from my sources, as before. The tallest light, Muckle Flugga, is 2.36 times the height of the Bell Rock but sees only 1.38 times as far for a 5 m eye, the square root law at work. The Bell Rock's own infobox gives a flash of 0.1 s in a 5 s period, so the light is on for 2.0% of the time. If the lens turns once in 5 s, which I am assuming, that flash matches a beam 7.2 degrees wide, whereas the model hyper-radial beam of How Lighthouses Work 4 (0.86 degrees) would last only 0.012 s. The page does not give the beam width or the rotation period, so the tension noted in How Lighthouses Work 5 between narrow beams and second-long flashes remains unresolved. Most of the other numbers in this chapter are tidier than that one.

Common mistakes
Sizing the lamp for good weather when the bad night is the harder requirement; buying a taller tower to fix a poor-visibility problem, or a brighter lamp to fix a horizon problem; quoting the chart range as the distance at which a small boat first sees the light; forgetting that the chart height is usually from high water, so the light stands higher at low tide; choosing a characteristic without checking the neighbours; reading Fl(3) as three seconds instead of three flashes; mixing up the number of flashes in a group with the period; calling any light that flashes a fixed light; treating my 3 s confusion rule, the 1 s flashes and the invented headland as sourced facts; and treating a chapter of examples as a design for a real light.
Exercise 1

Plan a light for a second headland. The ground is 30 m above the sea, the ships' eyes are 10 m up, the light must be seen at 20 nm in standard weather (10 nm visibility) and at 8 nm in 2 nm visibility. Find the focal height needed for the horizon and the tower that gives it, the horizon range of towers of 10, 15, 20 and 25 m, the intensity each weather case needs and which one decides, and the nominal range for 1, 2, 4 and 10 times the larger intensity.

๐Ÿ“„ View solution
Exercise 2

Choose a characteristic between neighbours that show Fl(2) W 10s, Fl W 8s and Oc W 6s. Test the six candidates Fl(3) W 15s, Fl W 10s, Fl(2) W 12s, Oc W 6s, Fl W 3s and Iso W 8s against the single-flash and group rules and the 3 s confusion rule. Then write a function that identifies a light from the start times of its flashes, and use it on three stopwatch lists, and give the shortest watch that shows two full periods of the slowest candidate.

๐Ÿ“„ View solution
Exercise 3

Read five chart labels: Fl W 5s 28m 18M, Oc W 6s 20m 12M, Iso W 4s 15m 10M, Fl(2) W 10s 45m 25M and LFl W 12s 30m 16M. Parse each, and for eyes at 2, 5 and 10 m give the horizon range and say whether the horizon or the brightness limits it. Find how many minutes a boat at 6 knots takes to reach each light from first sight with a 5 m eye, and how much farther each light can be seen at low water if the tide is 4 m below the chart datum (an assumption).

๐Ÿ“„ View solution

Quick Reference

  • The plan: choose the horizon (height), the brightness (intensity), the characteristic and the site, in that order; what is seen is the smaller of the horizon and luminous ranges
  • Formulas: geographic range = 2.084 (โˆšH + โˆšh) nm with heights in metres; luminous range by Allard's law to 0.2 microlux, solved by bisection
  • Worked example: 15 nm clear and 6 nm in 2 nm visibility needs 19.1 m of focal height and 197,562 cd; the poor-weather case decides the lamp
  • Characteristic: Fl(3) W 15s chosen against neighbours Fl W 5s, Fl W 10s and Fl(2) W 20s; the 3 s confusion rule is my own
  • Chart label: class, colour, period, height above chart datum (usually high water), range in M; written "Fl(3) W 15s 32m 23M"
  • Real lights: Bell Rock Fl W 5s 28m 18M, 1,900,000 cd, flash 0.1 s; Skerryvore 46 m, 23 nm; Muckle Flugga 66 m, 22 nm
  • Conflicts: the light characteristics page calls the M range both "visible" and "nominal"; listed ranges for the Bell Rock and Skerryvore exceed the horizon for a 5 m eye; narrow beams against flashes of 0.1 s or more (unresolved)
Coming next
This is the last chapter in the plan for How Lighthouses Work, so there is no further chapter to preview. The course is complete: from the inverse square law and the horizon to the keepers and the automated lights, you now have the tools to read a lighthouse, and to plan one.