A sailboat can't sail straight into the wind, yet it can reach a buoy that sits dead upwind. Three ideas make that work. The wind you feel on a moving boat differs from the wind on shore. A sail works like an airplane wing standing on end, and the keel under the boat is a second wing working in water. And by zigzagging at the right angle, a boat gains ground toward the wind on every leg. Speeds are in knots, the sailor's unit: one nautical mile (1852 m) per hour, which is 1.151 mph.
The true wind is the wind you'd measure standing still on a dock. Ride a bike on a calm day and you feel a breeze in your face anyway: that's wind made by your own motion, blowing straight at you from wherever you're heading. On a boat the two add up, and the sum is the apparent wind, the only wind the sail ever feels. Sailors measure every wind direction as an angle from the bow (the front of the boat): 0° means pointing straight into the wind, 90° means wind from the side, 180° means wind from directly behind. Drag the boat to turn it and watch the gold arrow.
How to read this: wind blows from the top of the picture. The three arrows all end at the boat: the green one is the true wind, the amber one is the headwind from the boat's own motion, and the gold one is their sum, the wind the sail feels.
Try this: pick Ice boat, then press Accelerate from rest and watch the gold arrow swing toward the bow as the boat speeds up.
How to read this: the gold curve shows the apparent wind angle at every boat speed, for your heading and wind. The faster the boat goes, the further forward the wind swings. The craft can keep speeding up only while the curve stays above the red floor, its drag angle β.
Try this: lower the drag angle slider and watch the ceiling slide to the right, past the true wind speed.
TW is the true wind speed, BS the boat speed and θ the true wind angle from the bow (0° = head to wind). Moving forward adds a headwind of size BS, which is why BS appears with a plus sign along the boat. The formula is the law of cosines applied to the triangle in the picture.
Ice boats and foiling sailboats regularly sail faster than the wind that pushes them. Nothing is free here: the energy comes from the difference in speed between the moving air and the water or ice the boat grips. As the boat speeds up, the apparent wind gets stronger and swings toward the bow, and the crew pulls the sail in tighter to match. The sail keeps producing forward push as long as the apparent wind angle stays above the craft's drag angle β.
That gives a ceiling. By the law of sines in the wind triangle, the speed at which the apparent angle falls to β is TW·sin(θ − β) / sin β. Ice-boat blades and hydrofoils have so little drag that β is small, and the ceiling can be several times the wind speed. A keelboat has a large β and its hull's water resistance climbs steeply near its E06 · hull speed, so it stays well below the wind speed.
import math KN = 1852 / 3600 # one knot in m/s (exact) def apparent_wind(tw, bs, twa_deg): t = math.radians(twa_deg) # true wind angle from the bow x = tw*math.cos(t) + bs # along the boat: wind + headwind y = tw*math.sin(t) # across the boat return math.hypot(x, y), math.degrees(math.atan2(y, x)) def ceiling(tw, twa_deg, beta_deg): # law of sines if twa_deg <= beta_deg: return 0.0 return tw*math.sin(math.radians(twa_deg - beta_deg)) / math.sin(math.radians(beta_deg)) tw, twa = 15, 105 # knots, degrees (ice boat preset) for bs in [0, 10, 20, 30, 45]: aw, awa = apparent_wind(tw, bs, twa) print(f"BS {bs:4.1f} kn AW {aw:5.1f} kn angle {awa:5.1f} deg") print(f"ceiling at beta=10: {ceiling(tw, twa, 10):.0f} kn")
A sail curved and set at a small angle to the apparent wind bends the air, just like a E04 · wing. The air pushes back with two parts: lift, at right angles to the apparent wind, and drag, straight downwind. What the boat cares about is a different split: drive, the part along the boat's heading, and side force, the part pushing the boat sideways and tipping it over (heeling). Underwater, the keel is a second wing. The boat slips a few degrees sideways through the water (that slip is the leeway angle), so the keel meets the water at a small angle and makes its own lift, which cancels the side force. Point too close to the wind and the drive vanishes.
How to read this: the gold arrows are the apparent wind reaching the sail. Lift and drag on the sail add up to one total push, which splits into drive along the boat and side force across it. The blue arrow is the keel pushing back underwater.
Try this: press Pinching 32° and watch the amber drive arrow shrink while the red side force stays big.
How to read this: each point is the forward push left over after the keel's drag, at that heading. Below zero the boat slows down however you trim. The red band is the no-go zone.
Try this: slide boat speed down to 0 and watch the zero crossing move to a smaller angle.
β is the apparent wind angle, S the sail area, ρair = 1.225 kg/m³ and ρsea = 1025 kg/m³. εa is the sail's drag angle and εh the underwater one. The keel (Ak = 1.8 m², aspect ratio AR = 2.5, toy) needs speed to work: its lift grows with BS², so at low speed the boat has to slip sideways at a big angle to resist the same side force.
Close to the wind the lift points mostly sideways and the drag points mostly backward, so the forward part of lift can't beat the backward part of drag plus the keel's own drag. The last line of the equation says it compactly: the boat can only make headway when the apparent wind angle is bigger than the two drag angles added together.
Measured from the true wind, the no-go zone is wider, because moving forward swings the apparent wind toward the bow (lab 1). Most good keelboats can't sail closer than about 40–45° to the true wind; that's a typical figure, and it varies by boat and conditions. The side force also tips the boat; see E07 · Why sailboats don't tip over.
import math KN, RHO_AIR, RHO_SEA = 1852/3600, 1.225, 1025 S, CD0, K, CLMAX, A_STALL = 35, 0.12, 0.15, 1.4, 20 # toy sail EPS_H, AK, AR = 12.5, 1.8, 2.5 # toy keel def coef(a): # angle of attack in degrees if a <= 0: return 0.0, CD0 # sail luffs (flaps) if a <= A_STALL: cl = CLMAX*math.sin(a/A_STALL*math.pi/2) return cl, CD0 + K*cl*cl u = min(1, (a - A_STALL)/(90 - A_STALL)); s0 = math.sin(math.radians(A_STALL)) cl = CLMAX*math.cos(u*math.pi/2) return cl, CD0 + K*cl*cl + 1.25*(math.sin(math.radians(min(a, 180))) - s0)/(1 - s0) def forces(twa, bs, trim, tw=12): t = math.radians(twa) x, y = tw*math.cos(t) + bs, tw*math.sin(t) aw, b = math.hypot(x, y)*KN, math.atan2(y, x) # m/s, radians cl, cd = coef(math.degrees(b) - trim) q = 0.5*RHO_AIR*aw**2 L, D = q*S*cl, q*S*cd drive = L*math.sin(b) - D*math.cos(b) side = L*math.cos(b) + D*math.sin(b) net = drive - abs(side)*math.tan(math.radians(EPS_H)) qw = 0.5*RHO_SEA*(bs*KN)**2 slope = 2*math.pi*AR/(AR + 2) lee = math.degrees(abs(side)/(qw*AK*slope)) if qw else float("inf") return drive, side, net, lee best = max((forces(45, 5.5, d/4)[2], d/4) for d in range(361)) print("best trim", best[1], forces(45, 5.5, best[1]))
To reach a mark straight upwind, a boat sails at an angle to one side, then turns through the wind (a tack) and sails at the same angle to the other side. What counts is how fast it closes on the wind: its velocity made good (VMG), the part of the boat speed that points straight upwind. Sail too close to the wind and the boat crawls. Sail too wide and it's fast but heads mostly sideways. Somewhere in between is the best angle. A polar diagram shows how fast a boat goes at every angle to the wind, and from it you can find that angle.
How to read this: the mark sits straight upwind of the start. The amber boat zigzags at your angle, the gold one at the best angle, and the red one points straight at the mark and goes nowhere. All three share one clock.
Try this: set the tacking angle to 70°, press Race, and watch the gold boat win even though the amber one moves faster through the water.
How to read this: wind blows from the top. The distance from the center to the green curve is the boat speed when sailing in that direction. The highest point the curve reaches toward the top is the best VMG: the gold line touches it there.
Try this: change the true wind and see the curve grow while the best angle stays put.
How to read this: the curve is boat speed × cos(angle): how fast the boat closes on the wind. Its peak is the best angle. Past 90° it goes negative because the boat is moving away from the wind.
Try this: drag the tacking angle and watch the amber dot climb toward the peak.
D is the straight-line distance to the mark and n the number of legs. Every leg points at the same angle, so the time to the mark doesn't depend on how many times you tack (in this idealized race with instant tacks). The page finds θ* with a golden-section search.
| angle | boat speed | VMG | sailed | time |
|---|
Gold row: the best angle. Amber row: your angle.
Close-hauled at about 45°, the boat moves at roughly 70% of its speed toward the wind (cos 45° ≈ 0.71). Pointing higher loses more speed than it gains in direction; bearing away gains speed but wastes it going sideways. Real polars move the best angle a little with wind strength, and boats do the same zigzag downwind (gybing) because a dead run is often slower than angling off. For the forces that set a boat's top speed, see E06 · Hull speed & planing; for the mechanical advantage sailors use to trim sails, E03 · Levers, pulleys & gears.
import math KN = 1852/3600 def polar(twa, tw): # idealized boat speed, knots if twa <= 33: return 0.0 vmax = 7.0*(1 - math.exp(-tw/6.5)) up = 1 - math.exp(-(twa - 33)/5) down = 1 - 0.22*max(0, (twa - 100)/80)**2 return vmax*up*down vmg = lambda twa, tw: polar(twa, tw)*math.cos(math.radians(twa)) def best_vmg(tw): # golden-section search a, b, r = 33, 90, (math.sqrt(5) - 1)/2 for _ in range(80): c, d = b - r*(b - a), a + r*(b - a) if vmg(c, tw) > vmg(d, tw): b = d else: a = c return (a + b)/2 tw, D = 12, 1852 # knots, meters (one nautical mile) th = best_vmg(tw) print(f"best angle {th:.1f} deg, VMG {vmg(th, tw):.2f} kn") for a in [36, 40, th, 50, 60, 70, 80]: t = D/(vmg(a, tw)*KN) print(f"{a:5.1f} deg {polar(a, tw):.2f} kn {t/60:5.1f} min")