Mercurial > hg > python
comparison safe.py @ 23:1670a33e3e6d
from markup
author | Henry Thompson <ht@markup.co.uk> |
---|---|
date | Sat, 29 May 2021 11:07:34 +0100 |
parents | |
children | 6df2f6dcc809 |
comparison
equal
deleted
inserted
replaced
5:bd1db1ed4c25 | 23:1670a33e3e6d |
---|---|
1 #!/usr/bin/python3 | |
2 '''Find a safe landing space (i.e. in air, not above lava) near a cluster''' | |
3 import sys, math | |
4 | |
5 from util import * | |
6 from bisect import insort | |
7 | |
8 def usage(): | |
9 print("""Usage: safe.py [-d n] [filename] | |
10 n is maximum distance of landing to some point in the cluster, default is 10. | |
11 | |
12 Feed stdin with lines from the output of cluster.py, having produced | |
13 air.tsv with the same settings as the cluster input, and lava.tsv | |
14 with a lower-bound on Y of 0""") | |
15 | |
16 n=10.0 | |
17 if len(sys.argv)>1: | |
18 if sys.argv[1]=='-d': | |
19 sys.argv.pop() | |
20 n=float(sys.argv.pop(1)) | |
21 | |
22 if len(sys.argv)>1: | |
23 infile=open(sys.argv.pop(1)) | |
24 else: | |
25 infile=sys.stdin | |
26 | |
27 class Block: | |
28 '''Shared by Air and Lava, | |
29 holds points and columns. | |
30 Columns are dictionaries indexed by (x,z) coords, | |
31 value is upward-ordered list of pairs, closed intervals of y''' | |
32 def __init__(self,filename): | |
33 with open(filename,'r') as file: | |
34 self.readHeaders(file) | |
35 self.readPoints(file) | |
36 | |
37 cc=self.columns={} | |
38 tc={} | |
39 for p in self.points: | |
40 k=(p[0],p[2]) | |
41 y=p[1] | |
42 try: | |
43 yy=tc[k] | |
44 insort(yy,y) | |
45 except KeyError: | |
46 tc[k]=[y] | |
47 # convert to lists of intervals | |
48 for k,yy in tc.items(): | |
49 tyy=[yy] | |
50 ii=[] | |
51 while True: | |
52 clean=True | |
53 for j,yy in enumerate(tyy): | |
54 if len(yy)==1+(yy[-1]-yy[0]): | |
55 ii.append((yy[0],yy[-1])) | |
56 else: | |
57 clean=False | |
58 for i in range(len(yy)-1): | |
59 if yy[i]+1!=yy[i+1]: | |
60 ii+=(yy[0],yy[i]) | |
61 tyy=[yy[i+1:]]+tyy[j+1:] | |
62 break | |
63 if clean: | |
64 break | |
65 self.columns[k]=set(ii) # so we can merge later | |
66 | |
67 def readPoints(self,file): | |
68 file.readline() | |
69 self.points=[[float(i) for i in l.split('\t')[2].split(',')] for l in file] | |
70 | |
71 Block.readHeaders=readHeaders # from util | |
72 | |
73 class Air(Block): | |
74 pass | |
75 | |
76 A=Air('air.tsv') | |
77 | |
78 class Lava(Block): | |
79 pass | |
80 | |
81 L=Lava('lava.tsv') | |
82 | |
83 def d(p1,p2): | |
84 dx=p1[0]-p2[0] | |
85 dz=p1[1]-p2[1] | |
86 dy=p1[2]-p2[2] | |
87 return math.sqrt((dx*dx)+(dy*dy)+(dz*dz)) | |
88 | |
89 def safety(p): | |
90 ka=[((a[0],a[2]),d(a,p)) for a in A.points if d(a,p)<=n] | |
91 return [(k,A.columns[k[0]],L.columns[k[0]]) for k in ka if k[0] in L.columns] | |
92 | |
93 readHeaders(sys.modules['__main__'],infile,False) | |
94 for l in infile: | |
95 c=eval(l) | |
96 ss=[] | |
97 hits={} | |
98 misses=[] | |
99 for p in c: | |
100 ss=safety(p) | |
101 if ss: | |
102 for (k,a,l) in ss: | |
103 try: | |
104 (aa,ll)=hits[k] | |
105 aa.update(a) | |
106 ll.update(l) | |
107 except KeyError: | |
108 hits[k]=(a,l) | |
109 else: | |
110 misses.append(p) | |
111 print(c) | |
112 if hits: | |
113 print(' %s nearby landing columns'%len(hits)) | |
114 for k in sorted(hits.keys(),key=lambda k:k[1]): | |
115 aa,ll=hits[k] | |
116 print("%s@%0.1f: %s %s"%(k[0],k[1],sorted(list(aa)),sorted(list(ll)))) | |
117 else: | |
118 print(' No nearby landing zones') | |
119 | |
120 if infile!=sys.stdin: | |
121 infile.close() |