Speed Over Ground with Current Calculator
This speed over ground calculator combines a boat's velocity through the water with the set and drift of a current.
Run — free
Enter boat speed and direction, then current speed and the direction toward which it flows. The calculator resolves both vectors into east and north components, adds them, and returns speed over ground, course over ground, and useful component values. It supports knots, kilometres per hour, miles per hour, and metres per second for passage planning, training, and transparent navigation checks.
Enter through-water motion and current correctly
Start with the boat speed through the water, not a GPS speed that already includes current. Pair it with the direction in which the boat is moving through the water. Both direction fields use true bearings measured clockwise from north: north is 0 degrees, east is 90, south is 180, and west is 270. Current drift is the current's speed, while current set is the direction toward which the water flows. That last distinction matters because some weather descriptions name the direction a wind comes from, but a marine current set normally describes where the water is going. Use the same speed unit for boat speed and drift; the selected unit applies to both and to the primary speed-over-ground result. A bearing of 360 degrees is accepted as equivalent to north. If your source gives magnetic headings, apply the appropriate variation before using this true-bearing calculator. Also distinguish heading from actual through-water course when leeway is material: the vector calculation can only represent the direction you enter, so account for leeway separately before treating the result as a navigation prediction.
How speed and course over ground are calculated
The calculator treats each motion as a two-dimensional velocity vector. For a true bearing, its east component is speed multiplied by the sine of the bearing, and its north component is speed multiplied by the cosine. It computes those components for the boat and current, then adds east to east and north to north. The magnitude of the combined vector, found with the Pythagorean relationship, is speed over ground. Course over ground is derived with a two-argument arctangent using east and north, then normalized to a bearing from 0 up to but not including 360 degrees. This method handles following, opposing, and cross currents without special cases. The response includes resultant east and north velocity in the selected unit, speed over ground in that unit and in knots, and the difference between speed over ground and boat speed. That difference is a resultant speed effect, not simply the current drift, because a cross-current can change direction strongly while producing a smaller change in overall speed. Results are rounded to six decimal places so repeated API and browser calculations remain stable.
Use the result as a planning calculation
Use speed over ground to estimate progress along the resultant track and course over ground to see where the combined motion points. A following current generally raises speed over ground, an opposing current lowers it, and a cross current shifts course while also changing the resultant speed. The returned component values are useful for checking the geometry or feeding a later calculation. However, this is a single-state vector model: it assumes boat velocity and current remain constant over the interval being considered. Real currents vary with position, depth, tide, river discharge, and time, while steering, waves, leeway, and manoeuvres alter the boat vector. The result therefore supports route comparison, instruction, and short-interval estimates rather than replacing current charts, local notices, GPS observations, or a qualified navigator. For passage planning, divide the route into legs when conditions change and use conservative inputs. Recalculate underway with current observations, maintain a proper position fix, and follow applicable navigation rules. If the two vectors cancel exactly, the boat has zero speed over ground and no meaningful course over ground, so the course field is deliberately omitted.
What you can do with it
Estimate a tidal-current track
Combine expected boat motion with tidal set and drift to estimate the resulting course and speed over ground for a passage leg.
Compare routing choices
Test headings or departure conditions to see how an opposing, following, or cross current changes progress and track.
Teach marine vector addition
Show students the east and north components behind SOG and COG instead of presenting only an unexplained answer.
FAQ
What does the calculator cost?
It runs free in the browser. Each API request costs $0.002.
What are current set and drift?
Set is the true direction toward which the current flows. Drift is the current's speed.
Should I enter heading or course through the water?
Enter the direction of the boat's velocity through the water. If heading and through-water course differ because of leeway, account for leeway first.
Are directions true or magnetic?
They are true bearings measured clockwise from north. Convert magnetic values to true bearings before calculating.
Why can a cross current change speed over ground?
Perpendicular velocity adds vector magnitude as well as changing direction, so its effect is not limited to sideways displacement.
What happens if the boat and current cancel each other?
Speed over ground is zero and course over ground has no defined direction, so the course field is omitted.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/travel/speed-over-ground \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"boat_speed":6,"boat_course_degrees":90,"current_drift":2,"current_set_degrees":180}'const res = await fetch("https://api.kit.forhosting.com/travel/speed-over-ground", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"boat_speed": 6,
"boat_course_degrees": 90,
"current_drift": 2,
"current_set_degrees": 180
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/travel/speed-over-ground",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"boat_speed": 6,
"boat_course_degrees": 90,
"current_drift": 2,
"current_set_degrees": 180
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/travel/speed-over-ground", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"boat_speed":6,"boat_course_degrees":90,"current_drift":2,"current_set_degrees":180}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"boat_speed":6,"boat_course_degrees":90,"current_drift":2,"current_set_degrees":180}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/travel/speed-over-ground", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"boat_speed": 6,
"boat_course_degrees": 90,
"current_drift": 2,
"current_set_degrees": 180
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "travel.speed_over_ground",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |