Any sailors out there? Anyone learning to sail, or anyone who might teach sailing, may find this simple Codea script useful / informative in demonstrating the interaction of boat, tide, true wind and apparent wind vectors!
-- **************************************** -- Experimental Boat Tide and Wind vectors -- By Tony Southwood -- Copyright 2014 - All Rights Reserved -- **************************************** function setup() supportedOrientations(LANDSCAPE_ANY) displayMode(STANDARD) parameter.integer("boatHeading", 0,359,0) parameter.number("boatSpeed",0,10,10) parameter.integer("windSpeed",0,20,10) parameter.integer("windDirection",0,359,90) parameter.integer("tidalSet",0,359,0) parameter.number("tidalRate",0,5,0) parameter.integer("scale",1,25,20) end function draw() smooth() background(40, 40, 50) ox = WIDTH / 2 oy = HEIGHT / 2 bh = boatHeading bs = boatSpeed ts = tidalSet tr = tidalRate twn= windDirection twd = windDirection tws = windSpeed twa = 0 cd = 0 cs = 0 awn = 0 awd = 0 aws = 0 awa = 0 b = vec2(bs * math.cos(math.rad(bh)), bs * math.sin(math.rad(bh))) t = vec2(tr * math.cos(math.rad(ts)), tr * math.sin(math.rad(ts))) w = vec2(tws * math.cos(math.rad(twd)), tws * math.sin(math.rad(twd))) c = vec2(b.x + t.x, b.y + t.y) a = vec2(b.x + t.x + w.x, b.y + t.y + w.y) twa = math.abs(math.deg(b:angleBetween(w))) awa = math.floor(math.abs(math.deg(b:angleBetween(a)))) bv = vec2(b.x * scale, b.y * scale) bv = bv:rotate(math.rad(90)) bv.x = -bv.x tv = vec2(t.x * scale, t.y * scale) tv = tv:rotate(math.rad(90)) tv.x = -tv.x wv = vec2(w.x * scale, w.y * scale) wv = wv:rotate(math.rad(90)) wv.x = -wv.x cv = vec2(c.x * scale, c.y * scale) cv = cv:rotate(math.rad(90)) cv.x = -cv.x av = vec2(a.x * scale, a.y * scale) av = av:rotate(math.rad(90)) av.x = -av.x cs = math.sqrt((c.x * c.x) + (c.y * c.y)) cd = math.floor(math.deg(math.atan2(c.y, c.x))) if cd < 0 then cd = math.fmod(cd + 360,360) end aws = math.sqrt((a.x * a.x) + (a.y + a.y)) aws = math.sqrt(math.abs(a.x * a.x) + math.abs(a.y * a.y)) awd = math.deg(math.atan2(a.y, a.x)) if awd < 0 then awd = math.fmod(awd + 360, 360) end awn = math.fmod(awd + 180, 360) output.clear() -- Draw boat vector fontSize(14) strokeWidth(8) stroke(255,255,255,255) line(ox,oy,ox + bv.x, oy + bv.y) -- Draw Tide vector strokeWidth(8) stroke(42, 47, 203, 255) line(ox + bv.x, oy + bv.y, ox + bv.x + tv.x, oy + bv.y + tv.y) -- Draw Course made good strokeWidth(4) stroke(229, 14, 11, 126) line(ox,oy, ox + bv.x + tv.x, oy + bv.y + tv.y) -- Draw true Wind vector strokeWidth(8) stroke(68, 180, 34, 255) line(ox + bv.x + tv.x, oy + bv.y + tv.y, ox + bv.x + tv.x + wv.x, oy + bv.y + tv.y + wv.y) -- Draw Apparent wind vector strokeWidth(4) stroke(68, 180, 34, 127) line(ox, oy, ox + bv.x + tv.x + wv.x, oy + bv.y + tv.y + wv.y) textMode(CORNER) t = "Hdg: " ..bh .." Spd: " ..math.floor(bs * 100) / 100 .."k" t = t .." Tide: " ..ts .." x " ..math.floor(tr * 100) / 100 .."k" t = t .." CMG: " ..cd .." SMG: " ..math.floor(cs * 100) / 100 .."k" t = t .." Wind Bow Angles - True: " ..twa .." x " ..math.floor(tws * 100) / 100 .."k" t = t .." App: " ..awa .." x " ..math.floor(aws * 100) / 100 .."k" fill(252, 252, 252, 255) txtW = textSize(t) text(t, (WIDTH/2) - (txtW/2), 40) fontSize(40) t = "Playing with Wind and Tide" txtW = textSize(t) text(t, (WIDTH/2) - (txtW/2), HEIGHT - 50) end ```