PolarForge
A sailing performance tool for building, refining, and comparing polar diagrams from real on-the-water data.
Introduction
PolarForge takes raw sailing log data and turns it into an actionable polar diagram. Upload one or more Expedition CSV log files, compare recorded performance against a baseline polar, accept the cells where you beat it, and export the updated polar for use in navigation software.
The app ships with the F35 ORC 2022 polar pre-loaded as a demo baseline so you can explore the interface immediately without any data.
Workflow at a glance
Upload Performance Logs
PolarForge reads Expedition CSV log files — the standard export format from the Expedition navigation and routing application.
How to upload
Either drag and drop one or more .csv files onto the upload zone in the
Performance Logs panel (left sidebar), or click the zone to open a
file browser. You can also use the + Upload Logs button in the
header. Multiple files are merged into a single dataset.
Required CSV columns
| Column | Meaning | Required? |
|---|---|---|
TWS | True Wind Speed (knots) | Yes |
TWA | True Wind Angle (degrees, 0–180) | Yes |
BSP | Boat Speed through water (knots) | Yes |
Heel | Heel angle (degrees) — used by the heel filter | No |
SOG | Speed Over Ground — used by the SOG−BSP filter | No |
PolBspPC | % of polar speed — used by the max polar % filter | No |
TmToGun | Time to start gun (seconds) — enables race mode filter | No |
Utc | Timestamp — required for the timeline preview | No |
tws, TWS, Tws) are all accepted.
After uploading
When a file includes a Utc timestamp column, a
timeline preview modal opens automatically before the data is
imported. This lets you select only the racing segments you want. See
Timeline Selection for details.
Import a Baseline Polar
A baseline polar gives PolarForge a reference to measure your recorded data against. Without one, the recorded data is still displayed but no improvements can be detected.
Click ⬆ Import Polar in the header, then paste polar data into
the text box or upload a file (.pol, .txt,
.csv, or .json). Two formats are supported:
Expedition format
Tab-separated. Each data row starts with a TWS value followed by
TWA BSP pairs.
!Expedition polar
6.0 43.2 4.64 52.0 5.18 60.0 5.49 90.0 5.82
8.0 41.8 5.50 52.0 6.15 60.0 6.45 90.0 6.70
10.0 40.5 6.20 52.0 6.95 60.0 7.25 90.0 7.60
Grid CSV format
TWA values in the first column, TWS values as column headers, BSP values in the body.
TWA,6,8,10,12,16
30,3.2,4.1,5.0,5.5,6.0
45,4.5,5.5,6.2,6.8,7.4
60,5.2,6.3,7.1,7.7,8.3
90,5.8,6.9,7.8,8.4,9.0
JSON format
Nested object exported by PolarForge itself. Keys are TWS values; inner keys are TWA angles; values are BSP.
{ "6": { "43": 4.64, "52": 5.18 }, "8": { "41": 5.50, "52": 6.15 } }
Reading the Polar Chart
The polar diagram is a half-circle speed plot. Each point on a curve represents the boat speed achievable at a given wind angle for a specific true wind speed. The further from the centre, the faster the boat.
Axes
| Axis | Meaning |
|---|---|
| Horizontal | Wind angle — 0° = directly upwind (left), 90° = beam reach (right), 180° = downwind (bottom) |
| Concentric arcs | Boat speed — inner arcs are slower, outer arcs are faster |
| Each coloured curve | One true wind speed (TWS) band |
Legend — what the colours mean
Navigation
| Action | Effect |
|---|---|
| Scroll wheel | Zoom in/out |
| Middle-click drag / Alt + drag | Pan the chart |
| Hover | Show TWS / TWA / BSP tooltip |
| ⌂ Reset View | Return to default zoom and position |
Visualization Settings
The ⚙ Settings panel (right column) controls how data is aggregated and what is shown on the chart.
| Setting | Effect |
|---|---|
| Min samples per cell | Cells with fewer data points than this threshold are ignored. Default: 3. Raise it to require more evidence before a cell is plotted. |
| Aggregation method | How multiple data points in the same (TWS, TWA) bin are combined. Options: 95th percentile, 90th percentile, max, mean, median. 95th percentile is recommended for racing — it captures fast runs without being skewed by outliers. |
| Show data points | Render individual diamond markers for every raw sample. Useful for diagnosing outliers. |
| Show merged polar | Display the combined baseline + improvements result as a gold curve. |
| Show VMG angles | Overlay lines at the optimal upwind and downwind VMG angles for each wind speed. |
| Show raw baseline | Keep the original imported baseline visible after improvements have been applied (useful for a before/after comparison). |
| Smooth improvements | Use spline interpolation to fill angle gaps between improved cells, producing smoother merged curves. |
| Interpolate polar curves | Render curves at finer angular resolution (5°, 2°, or 1°) for smoother display. |
Direct Point Editing on the Chart
Individual data points on the polar diagram can be edited directly — no need to find the cell in the table. Hold the left mouse button on any curve point for 2 seconds to enter edit mode, then use the scroll wheel to adjust the value. The curve updates live as you scroll.
How to use it
The edit popup
| Element | Meaning |
|---|---|
| Header line | Identifies the point: TWS and TWA of the selected cell |
| Original | The BSP value before any editing |
| New | The current adjusted value and the delta (green = increase, red = decrease) |
| ✓ Accept | Saves the change and triggers a full recalculation (improvements, VMG, table) |
| Cancel | Discards the change; the curve snaps back to the original |
What updates live
While scrolling, the chart redraws the affected wind speed curve in real time. The gold dot tracks the new position along the radial line. The popup delta updates with each notch. Accept triggers a full refresh: improvements are re-evaluated, the VMG panel updates, and the table reflects the new value.
Data Filters
All uploaded CSV data passes through the Data Filters panel before it is added to the polar. Filters remove unreliable or non-sailing data points. All active filters are combined with AND logic — a point must pass every filter to be included.
| Filter | What it removes | Typical value |
|---|---|---|
| Min heel angle (°) | Points where the boat is nearly flat — likely motoring, drifting, or at anchor. | 3–5° |
| Min BSP (kts) | Points below a minimum boat speed — catches drifting and very slow maneuvers. | 1–2 kts |
| Min TWS (kts) | Removes unreliable data in very light air where sensors are noisy. | 4–6 kts |
| Max polar % (PolBspPC) | Removes points exceeding a percentage of the theoretical polar speed — likely engine-assisted. Only active if the CSV contains a PolBspPC column. |
110–120% |
| Max SOG−BSP delta (kts) | If Speed Over Ground greatly exceeds Boat Speed, the boat is likely motoring into a current or under power. Only active if the CSV contains SOG. |
2–3 kts |
| Race mode (TmToGun) | Restricts import to rows where the start timer is active. Options: All data (no filter), Timer active (pre-start + race), After gun (race only). Only active if the CSV contains TmToGun. |
After gun |
Wind Speed Filter
The Wind Speed Filter panel shows a button for every TWS band present in your data. Clicking a band toggles its visibility on the polar chart. This lets you focus on specific wind conditions without deleting any data.
Toggle All shows or hides every band at once.
Timeline Selection
When an uploaded CSV file contains a Utc timestamp column, a
timeline preview modal opens before the data is imported. This
lets you select only the portions of the log you want — typically, the clean
upwind and downwind legs of a race, excluding start-line chaos, mark roundings,
and any time spent motoring.
Reading the timeline chart
The chart shows the full session as a multi-line overlay:
| Line colour | Signal |
|---|---|
| Blue | Boat speed (BSP, knots) |
| Orange | Heel angle (degrees) |
| Purple | Speed Over Ground (SOG, knots) |
| Green | True Wind Speed (TWS, knots) |
| Light green shading | Start timer active (pre-start + race) |
| Tan shading | Pre-start period (TmToGun > 0) |
Selecting segments
Improvements
After importing data, PolarForge compares every (TWS, TWA) cell in the recorded polar against the corresponding cell in the baseline. Cells where your recorded speed exceeds the baseline are called improvements and are shown in green on the chart.
Improvement banner
When improvements are found, a banner appears at the top of the page showing a summary: number of improved cells per wind speed and the average percentage gain. Click ☰ Details to expand the full list.
Reading the details panel
Improvements are grouped by wind speed. For each cell you'll see:
| Column | Meaning |
|---|---|
| TWA | The wind angle of the improved cell |
| Old → New | Baseline BSP → recorded BSP (in knots) |
| Gain (kt) | Absolute speed improvement |
| Gain (%) | Percentage improvement over baseline |
| ★ | New angle — present in recorded data but absent from the baseline |
Applying improvements
Once you are satisfied that an improvement is genuine (not noise), apply it to merge it into the base polar:
| Action | How |
|---|---|
| Apply all at once | Click Apply All in the banner |
| Apply by wind speed | Click ✓ Apply 12kt (etc.) inside the details panel |
| Apply one cell | Click an individual improvement entry in the details panel |
Confidence scaling
Larger claimed improvements require proportionally more supporting samples. A cell claiming a 10% gain needs significantly more data points before it is accepted than one claiming a 1% gain. This prevents a handful of lucky fast runs from inflating your polar.
Polar Data Table
Below the polar chart, a data table displays all polar values in a grid with TWA angles as rows and TWS bands as columns. It is the main place to review and understand what is in your polar.
Table views
Three views are available via buttons above the table:
| View | What it shows |
|---|---|
| Speed |
BSP values in knots. Colour-coded:
|
| Coverage | Sample count per cell rather than speed. Shading intensity indicates density: blank = no samples, light = <50, medium = 50–500, dark = >500. Use this to identify which cells have enough data to be reliable. |
| Compare | Visible only when a comparison polar (Polar B) is loaded. Shows Polar B values and % difference. Green = B is faster, red = A is faster. |
Editing Cells
Any cell in the Speed view can be edited manually. Click a cell to enter edit mode; the cell turns into an input field.
| Key | Action |
|---|---|
| Enter | Confirm the value and apply the change |
| Escape | Cancel without saving |
| Tab | Confirm and move to the next cell to the right |
Enter a positive number to set a new BSP, or leave the field blank to clear the cell.
Editing column headers
Double-click a TWS column header to rename the wind speed value. Hover a header to reveal a × Delete button that removes the entire column.
Adding rows and columns
| Button | Effect |
|---|---|
| + Add TWA Row | Inserts a new angle row. The app suggests the largest gap in existing angles. |
| + Add TWS Column | Inserts a new wind speed column. Suggests the next step after your highest existing TWS. |
| Clear Recorded Data | Removes all CSV-imported data, leaving only the base polar intact. |
VMG Optimal Angles
The VMG Optimal Angles panel shows the best angle and speed for each wind speed band in your polar. VMG (Velocity Made Good) is the component of boat speed that is actually making progress toward the target — directly upwind or downwind.
For each TWS the panel shows two rows:
| Row | Meaning |
|---|---|
| ↑ Upwind | The TWA that maximises progress directly into the wind. Sail this angle (or the layline) to get upwind fastest. |
| ↓ Downwind | The TWA that maximises progress directly downwind. |
VMG is calculated as: BSP × cos(TWA) for upwind and
BSP × cos(180° − TWA) for downwind.
Session Statistics
The Session Stats panel (appears when log data is loaded) shows a quick summary of your imported data:
| Stat | Meaning |
|---|---|
| Data Points | Points passing filters / total raw points in uploaded logs |
| Max BSP | Fastest boat speed recorded (knots) |
| Avg BSP | Average boat speed across all filtered points |
| TWS Range | Minimum and maximum true wind speed in the filtered dataset |
| Improvements | Number of (TWS, TWA) cells where recorded data beats the baseline |
| Avg Gain | Average percentage improvement across all improved cells |
Compare Polars
The Compare Polar panel lets you load a second polar (Polar B) to compare side-by-side with your base polar (Polar A).
Polar B is also rendered as a purple curve in the diagram.
Fill angle extremes
If Polar B has data at extreme angles (very low or very high TWA) that your base polar lacks, clicking Fill angle extremes copies those cells from B into A. This is useful when extending a manually trimmed polar with data from a more complete source.
Clear
Click Clear in the Compare Polar panel to remove Polar B entirely.
Exporting Data
Three export buttons are available in the header. All exports use the merged polar (baseline + any applied improvements).
| Export | Format | Best for |
|---|---|---|
| ⬇ Export Grid CSV | TWA rows × TWS columns grid | Spreadsheet analysis, importing into other tools |
| ⬇ Export Expedition | Expedition !polar tab-separated format |
Loading directly into Expedition navigation software |
| ⬇ Export JSON | Nested JSON object | Programmatic processing, version control, archiving |
Key Concepts
True Wind Speed (TWS)
The actual wind speed, independent of the boat's motion. This is the primary grouping dimension for polar data — performance is compared only within the same wind speed band.
True Wind Angle (TWA)
The angle between the wind direction and the boat's heading, measured from 0° (directly into the wind) to 180° (directly downwind). Pointing 45° off the wind is a close-hauled upwind angle; 150° is a broad reach or deep downwind angle.
Boat Speed (BSP)
Speed through water, not affected by current. This is the key performance metric. Speed Over Ground (SOG) includes current effects and is used only for filtering.
Baseline polar
The reference curve — usually an ORC or IMS rating polar, a manufacturer specification, or a previous season's best. All improvements are measured relative to this.
Merged polar
The final combined polar: baseline values are used where no improvement exists; improved values replace the baseline where recorded data is better. This is what you export.
Aggregation method
When multiple logged data points fall in the same (TWS, TWA) bin, they are combined by the selected aggregation method. The 95th percentile is recommended for racing polars — it represents a genuinely fast run rather than the average, while still being robust against the occasional freak reading.
Tips & Tricks
Getting clean data
- Use the timeline to select only steady sailing legs — long upwind or downwind stretches produce the best signal.
- Set a minimum heel angle of 3–5° to exclude any motoring or drifting data.
- The After gun race mode filter automatically excludes pre-start maneuvers when the CSV contains a
TmToGuncolumn.
Building confidence
- Switch to the Coverage view before applying improvements — a cell with fewer than 20 samples is unlikely to be reliable.
- Raise min samples per cell to 5–10 if you have a lot of data; this filters out bins with very few observations.
- Upload logs from multiple races in the same wind range to accumulate samples across the same bins.
Refining the polar
- Apply improvements wind speed by wind speed. Carefully review any cell claiming a gain of more than 5% — that level of improvement warrants more data.
- Edit individual cells manually if one value looks physically impossible (e.g. faster than hull speed).
- Enable Smooth improvements to interpolate naturally between the improved cells.
Version management
- Export a JSON snapshot at the end of each session.
- Load a previous snapshot as Polar B to quantify how much the polar has improved since last time.
Troubleshooting
| Problem | Solution |
|---|---|
| CSV fails to parse | Ensure the file has columns named TWS, TWA, and BSP (any case). Check that it is comma-separated and uses standard decimal notation. |
| No improvements detected | Check the filter stats — filters may be too strict. Try lowering min heel or min BSP. Also verify the baseline polar was imported correctly. |
| Polar diagram is empty | Either no data has been loaded or all wind speeds are toggled off in the TWS Filter panel. The demo polar loads on startup if no baseline has been imported. |
| Data looks very noisy or scattered | Raise min samples per cell, apply stricter filters, or use the timeline to exclude chaotic segments (mark roundings, tacks). |
| A specific wind speed is missing from the chart | Check the TWS Filter panel — that band may be toggled off. Also check whether the baseline polar has data at that wind speed. |
| An improvement looks unrealistically large | Switch to Coverage view to check the sample count for that cell. Very few samples (1–3) can produce spurious results. Raise the min samples threshold or investigate the raw data. |
| Timeline modal does not appear | The CSV must contain a Utc timestamp column. Without it, data is imported directly without a timeline preview. |
PolarForge — built for racing sailors. github.com/maelms/polar-alaya