Added Colors for lilaneks
[Lilanci.git] / geometry.c
blobac4205b13f9b4729fb7cfb4b242edb8a50fe8315
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, *pc;
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 Poly *tp;
290 a->nopol += 1;
291 a->p = realloc(a->p, sizeof(Poly *)*a->nopol);
292 a->p[a->nopol-1] = TranslatePolyXY(p, 0, 0);
294 return true;
297 int InArea(Area *a, Vect *v){
298 int i;
299 for(i=0; i<a->nopol; i++){
300 if(InPoly(a->p[i], v))
301 return true;
303 return false;
306 int AreaInArea(Area *a1, Area *a2){
307 int i,j;
309 if(a1 == 0 || a2==0)
310 return false;
312 for(i=0; i<a1->nopol; i++)
313 for(j=0; j<a2->nopol; j++)
314 if(PolyInPoly(a1->p[i], a2->p[j]))
315 return true;
316 return false;
319 int AreaInAreaComp(Area *a1, Area *a2){
320 //TODO: rewrite to correct behavior this is only sufficient behavior to current use in ebulanci but not correct
321 int i,j;
322 int aia;
324 if(a1 == 0 || a2==0)
325 return false;
327 aia=true;
328 for(i=0; i<a1->nopol; i++)
329 for(j=0; j<a2->nopol; j++){
330 if(!PolyInPolyComp(a1->p[i], a2->p[j]))
331 aia =false;
333 return aia;
336 Area *TranslateAreaXY(Area *a, double x, double y){
337 Area *new;
338 Poly *p;
339 int i;
341 new = NewArea();
342 for(i=0; i< a->nopol; i++){
343 p = TranslatePolyXY(a->p[i], x, y);
344 AddToArea(new, p);
345 FreePoly(p);
348 return new;
351 Area *TranslateArea(Area *a, Vect *v){
352 return TranslateAreaXY(a, v->x, v->y);
355 void PrintArea(Area *a){
356 //TODO:dopsat;
359 char *Area2String(Area *a){
360 int i,al;
361 char *buf, *chain;
362 chain = 0;
363 buf = malloc(sizeof(char)* P2SBUFSIZE);
364 snprintf(buf, P2SBUFSIZE, "%d\n", a->nopol);
365 chain = strdup(buf);
366 al = strlen(chain)+1;
367 free(buf);
368 for(i=0; i<a->nopol; i++){
369 buf = Poly2String(a->p[i]);
370 al += strlen(buf)+2; //+2 for \n
371 chain = realloc(chain, al);
372 sprintf(&chain[strlen(chain)], "%s\n", buf);
373 FreePoly2String(buf);
375 return chain;
378 void FreeArea2String(char *s){
379 free(s);
382 Area *String2Area(char *s){
383 //TODO: return values check
384 char *cur;
385 Poly *tp;
386 Area *a;
387 int nopol, i;
389 a = NewArea();
390 sscanf(s, "%d", &nopol);
391 cur = s;
393 for(i=0; i<nopol; i++){
394 cur = strstr(&cur[strlen("\n")], "\n"); //BUG: if strlen("\n")>1 && strlen(nopol)==1
395 tp = String2Poly(cur);
396 AddToArea(a, tp);
397 FreePoly(tp);
400 return a;