diff --git a/airpower/__init__.py b/airpower/__init__.py index ac0783a3..ca3e9b85 100644 --- a/airpower/__init__.py +++ b/airpower/__init__.py @@ -1,241 +1,5 @@ print("airpower") -import airpower.altitude as apaltitude -import airpower.azimuth as apazimuth - from airpower.draw import * -from airpower.azimuth import setnorth - -import numpy as np - -import matplotlib -import matplotlib.pyplot as plt -matplotlib.rcParams['figure.figsize'] = [7.5, 10] -plt.rcParams.update({'font.size': 10}) - -class Aircraft: - - def __init__(self, name, x, y, azimuth, altitude): - self.turn = 0 - self.name = name - self.x = x - self.y = y - self.facing = apazimuth.tofacing(azimuth) - self.altitude = altitude - self.saved = [] - self._save(0) - self.drawatend() - - def __str__(self): - return "%s: (%.2f,%.2f) %03d %s %02d" % (self.name, self.x, self.y, self.facing, fromfacing(self.facing), self.altitude) - - def _restore(self, i): - self.x, self.y, self.facing, self.altitude = self.saved[i] - - def _save(self, i): - if len(self.saved) == i: - self.saved.append(None) - self.saved[i] = (self.x, self.y, self.facing, self.altitude) - - def _maxprevturn(self): - return len(self.saved) - 1 - - def drawflightpath(self, lastx, lasty): - drawlineinhex(lastx, lasty, self.x, self.y, color="lightgrey", linestyle="dashed", zorder=0.5) - - def drawbeforeend(self): - drawdartinhex(self.x, self.y, self.facing, dy=-0.02, size=0.5, color="grey") - drawtextinhex(self.x, self.y, self.facing, self.name, dx=-0.3, dy=0.0, size=7, color="grey") - drawtextinhex(self.x, self.y, self.facing, "%2d" % self.altitude, dx=+0.3, dy=0.0, size=7, color="grey") - - def drawatend(self): - drawdartinhex(self.x, self.y, self.facing, dy=-0.02, size=0.5) - drawtextinhex(self.x, self.y, self.facing, self.name, dx=-0.3, dy=0.0, size=7) - drawtextinhex(self.x, self.y, self.facing, "%2d" % self.altitude, dx=+0.3, dy=0.0, size=7) - - def _H(self): - dx = { - 0: +1.00, - 30: +1.00, - 60: +0.50, - 90: +0.00, - 120: -0.50, - 150: -1.00, - 180: -1.00, - 210: -1.00, - 240: -0.50, - 270: -0.00, - 300: +0.50, - 330: +1.00 - } - dy = { - 0: +0.00, - 30: +0.50, - 60: +0.75, - 90: +1.00, - 120: +0.75, - 150: +0.50, - 180: +0.00, - 210: -0.50, - 240: -0.75, - 270: -1.00, - 300: -0.75, - 330: -0.50 - } - self.x += dx[self.facing] - self.y += dy[self.facing] - - def onedge(self): - if self.x % 1 != 0: - return True - elif self.x % 2 == 0 and self.y % 1 == 0.5: - return True - elif self.x % 2 == 1 and self.y % 1 == 0.0: - return True - else: - return False - - def _R(self, pointingchange): - if self.onedge(): - if self.facing == 0: - self.y -= 0.5 - elif self.facing == 60: - self.x += 0.50 - self.y -= 0.25 - elif self.facing == 120: - self.x += 0.50 - self.y += 0.25 - elif self.facing == 180: - self.y += 0.5 - elif self.facing == 240: - self.x -= 0.50 - self.y += 0.25 - elif self.facing == 300: - self.x -= 0.50 - self.y -= 0.25 - self.facing = (self.facing + 360 - pointingchange) % 360 - - def _L(self, pointingchange): - if self.onedge(): - if self.facing == 0: - self.y += 0.5 - elif self.facing == 60: - self.x -= 0.50 - self.y += 0.25 - elif self.facing == 120: - self.x -= 0.50 - self.y -= 0.25 - elif self.facing == 180: - self.y -= 0.5 - elif self.facing == 240: - self.x += 0.50 - self.y -= 0.25 - elif self.facing == 300: - self.x += 0.50 - self.y += 0.25 - self.facing = (self.facing + pointingchange) % 360 - - def _D(self, altitudechange): - self.altitude -= altitudechange - - def _C(self, altitudechange): - self.altitude += altitudechange - - def _report(self, s): - print("%s: turn %d: %s" % (self.name, self.turn, s)) - - def _reportfp(self, s): - print("%s: turn %d: FP %d: %s" % (self.name, self.turn, self.ifp, s)) - - def start(self, turn, nfp, s): - - if turn > self._maxprevturn() + 1: - raise ValueError("turn %d is out of sequence." % turn) - - self.turn = turn - self.nfp = nfp - self.ifp = 0 - self.ihfp = 0 - self.ivfp = 0 - self._restore(turn - 1) - - self.initialaltitude = self.altitude - - self._report("--- start of turn ---") - self._report("%d FPs available." % self.nfp) - self._report("initial azimuth = %s." % apazimuth.toazimuth(self.facing)) - self._report("initial altitude = %5.2f (%s)" % (self.altitude, apaltitude.altitudeband(self.altitude))) - - if s != "": - self.next(s) - - def next(self, s): - - lastx = self.x - lasty = self.y - altitudechange = 1 - - for t in s.split(","): - - self.ifp = self.ifp + 1 - - self._reportfp("movement code is %s." % t) - - if t[0] == 'H': - self.ihfp = self.ihfp + 1 - elif t[0] == 'D' or t[0] == 'C': - self.ivfp = self.ivfp + 1 - else: - raise ValueError("movement code must begin with H, D, or C.") - - for c in t: - if c == 'H': - self._H() - elif c == 'C': - self._C(altitudechange) - altitudechange = 1 - elif c == 'D': - self._D(altitudechange) - altitudechange = 1 - elif c == '¼': - altitudechange = 1/4 - elif c == '½': - altitudechange = 1/2 - elif c == '¾': - altitudechange = 3/4 - elif c == 'L': - self._L(30) - elif c == 'R': - self._R(30) - else: - raise ValueError("unknown movement code %s" % c) - - self.drawflightpath(lastx, lasty) - lastx = self.x - lasty = self.y - - self._reportfp("%d HFPs and %d VFPs used." % (self.ihfp, self.ivfp)) - - if self.ifp < self.nfp: - - self._reportfp("%d FPs remaining." % (self.nfp - self.ifp)) - - self.drawbeforeend() - - elif self.ifp == self.nfp: - - self._report("all %d FPs used." % (self.nfp)) - - self._report("final azimuth = %s." % apazimuth.toazimuth(self.facing)) - self._report("final altitude = %5.2f (%s)" % (self.altitude, apaltitude.altitudeband(self.altitude))) - if apaltitude.altitudeband(self.initialaltitude) != apaltitude.altitudeband(self.altitude): - self._report("altitude band changed from %s to %s." % (apaltitude.altitudeband(self.initialaltitude), apaltitude.altitudeband(self.altitude))) - self._report("--- end of turn ---") - - self._save(self.turn) - - self.drawatend() - - else: - - raise ValueError("only %d FPs are available." % self.nfp) +from airpower.aircraft import Aircraft +from airpower.azimuth import setnorth diff --git a/airpower/aircraft.py b/airpower/aircraft.py index 9e881fab..9026672a 100644 --- a/airpower/aircraft.py +++ b/airpower/aircraft.py @@ -35,14 +35,14 @@ def drawflightpath(self, lastx, lasty): apdraw.drawlineinhex(lastx, lasty, self.x, self.y, color="lightgrey", linestyle="dashed", zorder=0.5) def drawbeforeend(self): - apdraw.drawdartinhex(self.x, self.y, self.facing, dy=-0.02, size=0.5, color="grey") - apdraw.drawtextinhex(self.x, self.y, self.facing, self.name, dx=-0.3, dy=0.0, size=7, color="grey") - apdraw.drawtextinhex(self.x, self.y, self.facing, "%2d" % self.altitude, dx=+0.3, dy=0.0, size=7, color="grey") + apdraw.drawdart(self.x, self.y, self.facing, dy=-0.02, size=0.5, color="grey") + apdraw.drawtext(self.x, self.y, self.facing, self.name, dx=-0.3, dy=0.0, size=7, color="grey") + apdraw.drawtext(self.x, self.y, self.facing, "%2d" % self.altitude, dx=+0.3, dy=0.0, size=7, color="grey") def drawatend(self): - apdraw.drawdartinhex(self.x, self.y, self.facing, dy=-0.02, size=0.5) - apdraw.drawtextinhex(self.x, self.y, self.facing, self.name, dx=-0.3, dy=0.0, size=7) - apdraw.drawtextinhex(self.x, self.y, self.facing, "%2d" % self.altitude, dx=+0.3, dy=0.0, size=7) + apdraw.drawdart(self.x, self.y, self.facing, dy=-0.02, size=0.5) + apdraw.drawtext(self.x, self.y, self.facing, self.name, dx=-0.3, dy=0.0, size=7) + apdraw.drawtext(self.x, self.y, self.facing, "%2d" % self.altitude, dx=+0.3, dy=0.0, size=7) def _H(self): dx = { diff --git a/airpower/draw.py b/airpower/draw.py index 116a0be1..bc1294f4 100644 --- a/airpower/draw.py +++ b/airpower/draw.py @@ -19,19 +19,19 @@ def hextophysical(x,y): def physicaltohex(x,y): return x / np.sqrt(3/4), y -def drawhex(x, y, size=1, color="lightgrey"): +def _drawhexinphysical(x, y, size=1, color="lightgrey"): # size is inscribed diameter azimuths = np.array((0, 60, 120, 180, 240, 300, 0)) xvertices = x + 0.5 * size * cosd(azimuths) / cosd(30) yvertices = y + 0.5 * size * sind(azimuths) / cosd(30) plt.plot(xvertices, yvertices, color=color, zorder=0) -def drawdot(x, y, size=1, facing=0, dx=0, dy=0, color="black"): +def _drawdotinphysical(x, y, size=1, facing=0, dx=0, dy=0, color="black"): x = x + dx * sind(facing) + dy * cosd(facing) y = y - dx * cosd(facing) + dy * sind(facing) plt.plot(x, y, marker=".", color=color, zorder=1) -def drawsquare(x, y, facing, size=1, dx=0, dy=0, color="black"): +def _drawsquareinphysical(x, y, facing, size=1, dx=0, dy=0, color="black"): # size is diagonal x = x + dx * sind(facing) + dy * cosd(facing) y = y - dx * cosd(facing) + dy * sind(facing) @@ -42,10 +42,10 @@ def drawsquare(x, y, facing, size=1, dx=0, dy=0, color="black"): yvertices = y + 0.5 * size * sind(azimuths + facing) plt.plot(xvertices, yvertices, color=color, zorder=1) -def drawline(x0, y0, x1, y1, color="black", linestyle="solid", zorder=1): +def _drawlineinphysical(x0, y0, x1, y1, color="black", linestyle="solid", zorder=1): plt.plot((x0, x1), (y0, y1), linestyle=linestyle, color=color, zorder=zorder) -def drawarrow(x, y, facing, size=1.0, dx=0, dy=0, color="black"): +def _drawarrowinphysical(x, y, facing, size=1.0, dx=0, dy=0, color="black"): # size is length x = x + dx * sind(facing) + dy * cosd(facing) y = y - dx * cosd(facing) + dy * sind(facing) @@ -55,7 +55,7 @@ def drawarrow(x, y, facing, size=1.0, dx=0, dy=0, color="black"): y1 = y0 + 1.0 * size * sind(facing) plt.arrow(x0, y0, x1 - x0, y1 - y0, width=0.01, head_width=0.1, color=color, length_includes_head=True, zorder=1) -def drawdart(x, y, facing, size=1.0, dx=0, dy=0, color="black"): +def _drawdartinphysical(x, y, facing, size=1.0, dx=0, dy=0, color="black"): # size is length x = x + dx * sind(facing) + dy * cosd(facing) y = y - dx * cosd(facing) + dy * sind(facing) @@ -65,7 +65,7 @@ def drawdart(x, y, facing, size=1.0, dx=0, dy=0, color="black"): y1 = y0 + 1.0 * size * sind(facing) plt.arrow(x0, y0, x1 - x0, y1 - y0, width=0.02, head_length=size, head_width=0.5*size, color=color, length_includes_head=True, zorder=1) -def drawtext(x, y, facing, s, size=10, dx=0, dy=0, color="black"): +def _drawtextinphysical(x, y, facing, s, size=10, dx=0, dy=0, color="black"): x = x + dx * sind(facing) + dy * cosd(facing) y = y - dx * cosd(facing) + dy * sind(facing) plt.text(x, y, s, size=size, rotation=facing - 90, @@ -74,35 +74,35 @@ def drawtext(x, y, facing, s, size=10, dx=0, dy=0, color="black"): verticalalignment='center_baseline', rotation_mode="anchor") -def drawcompass(x, y): +def _drawcompassinphysical(x, y): facing = apazimuth.tofacing("N") - drawdot(x, y, size=0.3) - drawarrow(x, y, facing, 0.8, dy=+0.4) - drawtext(x, y, facing, "N", dy=0.95) + _drawdotinphysical(x, y, size=0.3) + _drawarrowinphysical(x, y, facing, size=0.8, dy=+0.4) + _drawtextinphysical(x, y, facing, "N", dy=0.95) -def drawhexinhex(x, y, **kwargs): - drawhex(*hextophysical(x, y), **kwargs) +def drawhex(x, y, **kwargs): + _drawhexinphysical(*hextophysical(x, y), **kwargs) -def drawdotinhex(x, y, **kwargs): - drawdot(*hextophysical(x, y), **kwargs) +def drawdot(x, y, **kwargs): + _drawdotinphysical(*hextophysical(x, y), **kwargs) -def drawsquareinhex(x, y, facing, **kwargs): - drawsquare(*hextophysical(x, y), facing, **kwargs) +def drawsquare(x, y, facing, **kwargs): + _drawsquareinphysical(*hextophysical(x, y), facing, **kwargs) def drawlineinhex(x0, y0, x1, y1, **kwargs): - drawline(*hextophysical(x0, y0), *hextophysical(x1, y1), **kwargs) + _drawlineinphysical(*hextophysical(x0, y0), *hextophysical(x1, y1), **kwargs) -def drawarrowinhex(x, y, facing, **kwargs): - drawarrow(*hextophysical(x, y), facing, **kwargs) +def drawarrow(x, y, facing, **kwargs): + _drawarrowinphysical(*hextophysical(x, y), facing, **kwargs) -def drawdartinhex(x, y, facing, **kwargs): - drawdart(*hextophysical(x, y), facing, **kwargs) +def drawdart(x, y, facing, **kwargs): + _drawdartinphysical(*hextophysical(x, y), facing, **kwargs) -def drawtextinhex(x, y, facing, s, **kwargs): - drawtext(*hextophysical(x, y), facing, s, **kwargs) +def drawtext(x, y, facing, s, **kwargs): + _drawtextinphysical(*hextophysical(x, y), facing, s, **kwargs) -def drawcompassinhex(x, y,**kwargs): - drawcompass(*hextophysical(x, y), **kwargs) +def drawcompass(x, y, **kwargs): + _drawcompassinphysical(*hextophysical(x, y), **kwargs) def drawhexgrid(sx, sy, nx, ny): matplotlib.rcParams['figure.figsize'] = [nx, ny * np.sqrt(3/4)] @@ -111,13 +111,7 @@ def drawhexgrid(sx, sy, nx, ny): plt.axis('off') for ix in range(sx, sx + nx): for iy in range(sy, sy + ny): - drawhexinhex(ix, iy + 0.5 * (ix % 2)) - -def drawinhex(x, y, facing): - #drawsquareinhex(x, y, facing, size=0.866) - drawdartinhex(x, y, facing, dy=-0.02, size=0.5) - drawtextinhex(x, y, facing, "F1", dx=-0.3, dy=0.0, size=7) - drawtextinhex(x, y, facing, "10", dx=+0.3, dy=0.0, size=7) + drawhex(ix, iy + 0.5 * (ix % 2)) def numbertohex(n): @@ -137,7 +131,7 @@ def numbertohex(n): return x, y def drawhexnumber(n): - drawtextinhex(*numbertohex(n), 90, "%04d" % n, dy=0.3, size=7, color="grey") + drawtext(*numbertohex(n), 90, "%04d" % n, dy=0.3, size=7, color="grey") def drawmapA1(): drawhexgrid(11,-16,19,15) @@ -149,4 +143,4 @@ def drawmapC1(): drawhexgrid(51,-16,19,15) for x in range(51,70): for y in range(1,16): - drawhexnumber(x * 100 + y) \ No newline at end of file + drawhexnumber(x * 100 + y)