WID comments
[Lilanci.git] / geometry.c
blob895044d6b736734887f7c9f55291389f39666efe
1 #include "geometry.h"
2 #include "util.h"
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <math.h>
6 #include <string.h>
8 void NormV(Vect *v){
9 double length;
11 length = v->x*v->x+v->y*v->y;
12 length = sqrt(length);
13 v->x /= length;
14 v->y /= length;
17 void PrintVect(Vect *a){
18 printf("[%lf, %lf]", a->x, a->y);
21 double DotProduct(Vect *a, Vect *b){
22 return a->x*b->x+a->y*b->y;
26 int InPoly(Poly *p, Vect *v){
27 int i;
29 for(i=0; i<p->novec; i++){
30 if( DotProduct(v, &p->n[i]) >= p->a[i]) return false;
33 return true;
37 Poly *NewPoly(){
38 Poly *p;
40 p=malloc(sizeof(Poly));
41 p->novec=p->alloc=0;
42 p->a=0;
43 p->n=0;
44 p->v=0;
46 return p;
49 int AddToPoly(Poly *p,Vect *v){
50 if( p->novec > (p->alloc-1)){
51 if(p->alloc <1)
52 p->alloc=1;
53 Vect *tn;
54 double *ta;
55 Vect *tv;
56 tn = realloc(p->n, sizeof(Vect)*p->alloc*2);
57 tv = realloc(p->v, sizeof(Vect)*p->alloc*2);
58 if(tn==0 || tv == 0)
59 return false;
61 p->n = tn;
62 p->v = tv;
64 ta = realloc(p->a, sizeof(double)*p->alloc*2);
65 if(ta == 0)
66 return false;
67 p->a = ta;
69 p->alloc *= 2;
72 p->v[p->novec].x = v->x;
73 p->v[p->novec].y = v->y;
75 if(p->novec){
76 //compute normal between actual and preceding
77 p->n[p->novec-1].x = -p->v[p->novec-1].y + p->v[p->novec].y;
78 p->n[p->novec-1].y = +p->v[p->novec-1].x - p->v[p->novec].x;
79 NormV(&p->n[p->novec-1]);
80 p->a[p->novec-1] = p->n[p->novec-1].x*v->x + p->n[p->novec-1].y*v->y;
82 //compute normal between actual and first
83 p->n[p->novec].x = -p->v[p->novec].y + p->v[0].y;
84 p->n[p->novec].y = +p->v[p->novec].x - p->v[0].x;
85 NormV(&p->n[p->novec]);
86 p->a[p->novec] = p->n[p->novec].x*v->x + p->n[p->novec].y*v->y;
89 p->novec++;
90 return true;
93 int AddToPolyXY(Poly *p, double x, double y){
94 Vect v;
95 v.x=x;
96 v.y=y;
97 return AddToPoly(p, &v);
100 void FreePoly(Poly *p){
101 if(p==0)return;
102 free(p->v);
103 p->v=0;
104 free(p->n);
105 p->n=0;
106 free(p->a);
107 p->a=0;
108 free(p);
111 Poly *NewRect(double x, double y, double xx, double yy){
112 Poly *p;
114 p=NewPoly();
115 AddToPolyXY(p, x, y);
116 AddToPolyXY(p, x+xx, y);
117 AddToPolyXY(p, x+xx, y+yy);
118 AddToPolyXY(p, x, y+yy);
120 return p;
123 int PolyInPoly(Poly *p1, Poly *p2){
124 int cur1;
125 int cur2;
127 //we check if any vertex of p1 is in p2
128 for(cur1=0; cur1 < p1->novec; cur1++){
129 if(InPoly(p2, &p1->v[cur1])){
130 return true;
134 //we check if any vertex of p1 is in p2
135 for(cur2=0; cur2 < p2->novec; cur2++){
136 if(InPoly(p1, &p2->v[cur2])){
137 return true;
141 return false;
144 int PolyInPolyComp(Poly *p1, Poly *p2){
145 int cur1;
146 int in;
147 int cur2;
149 //we check if every vertex of p1 is in p2
150 in = true;
151 for(cur1=0; cur1 < p1->novec; cur1++){
152 if(!InPoly(p2, &p1->v[cur1])){
153 in = false;
156 if(in)
157 return 1;
159 //we check if any vertex of p1 is in p2
160 in = true;
161 for(cur2=0; cur2 < p2->novec; cur2++){
162 if(!InPoly(p1, &p2->v[cur2])){
163 in = false;
166 if(in)
167 return 2;
169 return 0;
172 Poly *TranslatePoly(Poly *p, Vect *v){
173 return TranslatePolyXY(p, v->x, v->y);
176 Poly *TranslatePolyXY(Poly *p, double x, double y){
177 Poly *r;
178 int i;
180 r=NewPoly();
181 for(i=0; i< p->novec; i++){
182 AddToPolyXY(r, p->v[i].x+x, p->v[i].y+y);
184 return r;
187 void MultiplyPoly(Poly *p, double xm, double ym){
188 int i;
189 for(i=0; i< p->novec; i++){
190 p->v[i].x *= xm;
191 p->v[i].y *= ym;
196 void PrintPoly(Poly *p){
197 int i;
199 printf("NoV: %d\n", p->novec);
200 for(i=0; i<p->novec; i++)
201 printf("[%lf, %lf] [%lf, %lf] %lf \n", p->v[i].x, p->v[i].y, p->n[i].x, p->n[i].y, p->a[i]);
204 /* format for saving poly into string:
205 * space delimited values in ascii:
206 * novec x y x y x y ...
207 * */
208 #define P2SBUFSIZE 64
209 char *Poly2String(Poly *p){
210 int i;
211 char *buf;
212 char *chain;
213 int allocated;
215 buf = malloc(P2SBUFSIZE*sizeof(char));
216 chain = 0;
218 snprintf(buf, P2SBUFSIZE, "%d ", p->novec);
219 allocated = strlen(buf)+2;
220 chain = malloc(allocated*sizeof(char));
221 strcpy(chain, buf);
223 for(i=0; i<p->novec; i++){
224 snprintf(buf, P2SBUFSIZE, "%lf %lf ", p->v[i].x, p->v[i].y);
225 allocated += strlen(buf);
226 chain = realloc(chain, allocated*sizeof(char)); //TODO: check return value
227 sprintf(&chain[strlen(chain)],"%s", buf);
230 free(buf);
231 return chain;
234 void FreePoly2String(char *s){
235 free(s);
238 Poly *String2Poly(char *s){
239 //TODO: return values check, use strtok
240 char *cur;
241 Poly *p;
242 int novec, i;
243 double x,y;
245 p = NewPoly();
246 sscanf(s, "%d", &novec);
247 cur = s;
249 for(i=0; i<novec; i++){
250 cur = strchr(&cur[1], ' ');
251 sscanf(cur, "%lf", &x);
252 cur = strchr(&cur[1], ' ');
253 sscanf(cur, "%lf", &y);
254 AddToPolyXY(p, x, y);
257 return p;
261 Area *NewArea(){
262 Area *a;
264 a = malloc(sizeof(Area));
265 a->nopol = 0;
266 a->p = 0;
268 return a;
271 void FreeArea(Area *a){
272 int i;
274 if(a == 0)
275 return;
277 for(i=0; i< a->nopol; i++){
278 FreePoly(a->p[i]);
281 a->nopol = 0;
282 free(a->p);
283 a->p = 0;
284 free(a);
287 int AddToArea(Area *a, Poly *p){
288 //TODO: check for return values
289 a->nopol += 1;
290 a->p = realloc(a->p, sizeof(Poly *)*a->nopol);
291 a->p[a->nopol-1] = TranslatePolyXY(p, 0, 0);
293 return true;
296 int InArea(Area *a, Vect *v){
297 int i;
298 for(i=0; i<a->nopol; i++){
299 if(InPoly(a->p[i], v))
300 return true;
302 return false;
305 int AreaInArea(Area *a1, Area *a2){
306 int i,j;
308 if(a1 == 0 || a2==0)
309 return false;
311 for(i=0; i<a1->nopol; i++)
312 for(j=0; j<a2->nopol; j++)
313 if(PolyInPoly(a1->p[i], a2->p[j]))
314 return true;
315 return false;
318 int AreaInAreaComp(Area *a1, Area *a2){
319 //TODO: rewrite to correct behavior this is only sufficient behavior to current use in elilanci but not correct
320 int i,j;
321 int aia;
323 if(a1 == 0 || a2==0)
324 return false;
326 aia=true;
327 for(i=0; i<a1->nopol; i++)
328 for(j=0; j<a2->nopol; j++){
329 if(!PolyInPolyComp(a1->p[i], a2->p[j]))
330 aia =false;
332 return aia;
335 Area *TranslateAreaXY(Area *a, double x, double y){
336 Area *new;
337 Poly *p;
338 int i;
340 new = NewArea();
341 for(i=0; i< a->nopol; i++){
342 p = TranslatePolyXY(a->p[i], x, y);
343 AddToArea(new, p);
344 FreePoly(p);
347 return new;
350 Area *TranslateArea(Area *a, Vect *v){
351 return TranslateAreaXY(a, v->x, v->y);
354 void PrintArea(Area *a){
355 //TODO:dopsat;
358 char *Area2String(Area *a){
359 int i,al;
360 char *buf, *chain;
361 chain = 0;
362 buf = malloc(sizeof(char)* P2SBUFSIZE);
363 snprintf(buf, P2SBUFSIZE, "%d\n", a->nopol);
364 chain = strdup(buf);
365 al = strlen(chain)+1;
366 free(buf);
367 for(i=0; i<a->nopol; i++){
368 buf = Poly2String(a->p[i]);
369 al += strlen(buf)+2; //+2 for \n
370 chain = realloc(chain, al);
371 sprintf(&chain[strlen(chain)], "%s\n", buf);
372 FreePoly2String(buf);
374 return chain;
377 void FreeArea2String(char *s){
378 free(s);
381 Area *String2Area(char *s){
382 //TODO: return values check
383 char *cur;
384 Poly *tp;
385 Area *a;
386 int nopol, i;
388 a = NewArea();
389 sscanf(s, "%d", &nopol);
390 cur = s;
392 for(i=0; i<nopol; i++){
393 cur = strstr(&cur[strlen("\n")], "\n"); //BUG: if strlen("\n")>1 && strlen(nopol)==1
394 tp = String2Poly(cur);
395 AddToArea(a, tp);
396 FreePoly(tp);
399 return a;