xref: /inferno-os/appl/math/polyhedra.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1implement Polyhedra;
2
3include "sys.m";
4	sys: Sys;
5include "bufio.m";
6	bufio: Bufio;
7	Iobuf: import bufio;
8include "math/polyhedra.m";
9
10scanpolyhedra(f: string): (int, ref Polyhedron, ref Iobuf)
11{
12	first, last: ref Polyhedron;
13	D: int;
14
15	if(sys == nil)
16		sys = load Sys Sys->PATH;
17	if(bufio == nil)
18		bufio = load Bufio Bufio->PATH;
19	b := bufio->open(f, Sys->OREAD);
20	if(b == nil)
21		return (0, nil, nil);
22	n := 0;
23	for(;;){
24		s := getstring(b);
25		if(s == nil)
26			break;
27		n++;
28		p := ref Polyhedron;
29		if(first == nil)
30			first = p;
31		else{
32			last.nxt = p;
33			p.prv = last;
34		}
35		last = p;
36		p.name = s;
37		p.dname = getstring(b);
38		b.gets('\n');
39		(p.allf, p.adj) = scanvc(getstring(b));
40		b.gets('\n');
41		b.gets('\n');
42		b.gets('\n');
43		l := getstring(b);
44		(p.indx, l) = getint(l);
45		(p.V, l) = getint(l);
46		(p.E, l) = getint(l);
47		(p.F, l) = getint(l);
48		(nil, l) = getint(l);
49		(D, l) = getint(l);
50		(p.anti, l) = getint(l);
51		p.concave = D != 1 || p.allf;
52		p.offset = b.offset();
53		tot := 2*p.V+2*p.F;
54		for(i := 0; i < tot; i++)
55			b.gets('\n');
56		if(p.indx < 58 || p.indx == 59 || p.indx == 66 || p.indx == 67)
57			p.inc = 0.1;
58		else
59			p.inc = 0.0;
60		# sys->print("%d:	%d %d %d %d %s\n", p.indx, p.allf, D != 1, p.anti, p.concave, vc);
61	}
62	first.prv = last;
63	last.nxt = first;
64	return (n, first, b);
65}
66
67getpolyhedra(p: ref Polyhedron, b: ref Iobuf)
68{
69	q := p;
70	do{
71		getpolyhedron(q, b);
72		q = q.nxt;
73	}while(q != p);
74}
75
76getpolyhedron(p: ref Polyhedron, b: ref Iobuf)
77{
78	if(p.v != nil)
79		return;
80	b.seek(p.offset, Bufio->SEEKSTART);
81	p.v = array[p.V] of Vector;
82	for(i := 0; i < p.V; i++)
83		p.v[i] = getvector(b);
84	p.f = array[p.F] of Vector;
85	for(i = 0; i < p.F; i++)
86		p.f[i] = getvector(b);
87	p.fv = array[p.F] of array of int;
88	for(i = 0; i < p.F; i++)
89		p.fv[i] = getarray(b, p.adj);
90	p.vf = array[p.V] of array of int;
91	for(i = 0; i < p.V; i++)
92		p.vf[i] = getarray(b, p.adj);
93}
94
95getstring(b: ref Iobuf): string
96{
97	s := b.gets('\n');
98	if(s == nil)
99		return nil;
100	if(s[0] == '#')
101		return getstring(b);
102	if(s[len s - 1] == '\n')
103		return s[0: len s - 1];
104	return s;
105}
106
107getvector(b: ref Iobuf): Vector
108{
109	v: Vector;
110
111	s := getstring(b);
112	(v.x, s) = getreal(s);
113	(v.y, s) = getreal(s);
114	(v.z, s) = getreal(s);
115	return v;
116}
117
118getarray(b: ref Iobuf, adj: int): array of int
119{
120	n, d: int;
121
122	s := getstring(b);
123	(n, s) = getint(s);
124	a := array[n+2] of int;
125	a[0] = n;
126	for(i := 1; i <= n; i++)
127		(a[i], s) = getint(s);
128	(d, s) = getint(s);
129	if(d == 0 || d == n-1 || adj)
130		d = 1;
131	a[n+1] = d;
132	return a;
133}
134
135getint(s: string): (int, string)
136{
137	n := int s;
138	for(i := 0; i < len s && s[i] == ' '; i++)
139		;
140	for( ; i < len s; i++)
141		if(s[i] == ' ')
142			return (n, s[i+1:]);
143	return (n, nil);
144}
145
146getreal(s: string): (real, string)
147{
148	r := real s;
149	for(i := 0; i < len s && s[i] == ' '; i++)
150		;
151	for( ; i < len s; i++)
152		if(s[i] == ' ')
153			return (r, s[i+1:]);
154	return (r, nil);
155}
156
157vftab := array[] of { 0, 0, 0, 2, 3, 3, 5, 0, 3, 0, 3 };
158
159scanvc(s: string): (int, int)
160{
161	af := 0;
162	ad := 0;
163	fd := ld := 1;
164	ln := len s;
165	if(ln > 0 && s[0] == '('){
166		s = s[1:];
167		ln--;
168	}
169	while(ln > 0 && s[ln-1] != ')'){
170		s = s[0: ln-1];
171		ln--;
172	}
173	(m, lst) := sys->tokenize(s, ".");
174	for(l := lst ; l != nil; l = tl l){
175		(m, lst) = sys->tokenize(hd l, "/");
176		if(m == 1)
177			(n, d) := (int hd lst, 1);
178		else if(m == 2)
179			(n, d) = (int hd lst, int hd tl lst);
180		else
181			sys->print("vc error\n");
182		if(d != 1 && d == vftab[n])
183			af = 1;
184		if(d == n-1)
185			d = 1;
186		if(l == lst)
187			fd = d;
188		else if(ld != 1 && d != 1)
189			ad = 1;
190		ld = d;
191	}
192	if(ld != 1 && fd != 1)
193		ad = 1;
194	return (af, ad);
195}
196