1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 
5 #include "Membrane_shape.h"
6 
7 #define MEMCHUNK 512
8 #define MAX_LINES (1024 * 16)
9 #define MAX_TMP MAX_LINES
10 #define QUIET
11 
12 static int inCircle(int size, int x, int y);
13 static int inHexagon(int size, int x, int y);
14 
15 typedef int (*inShapePtr)(int, int, int);
16 
17 inShapePtr inShapes[SHAPE_N] = {inCircle, inHexagon};
18 
19 
inCircle(int size,int x,int y)20 static int inCircle(int size, int x, int y) {
21   //printf("in? %dx%d\n", x, y);
22   int result = 0;
23   x = abs(x);
24   y = abs(y);
25   // converts to euclidean distance
26   double y_ratio = sqrt(3);
27   double fx = (double) x;
28   double fy = (double) y;
29   fy *= y_ratio;
30 
31   double distance = sqrt((fx * fx) + (fy * fy));
32   if ((distance) < (size / 2)) {
33     result = 1;
34   }
35   return(result);
36 }
37 
38 //
39 
inHexagon(int size,int x,int y)40 static int inHexagon(int size, int x, int y) {
41   int result = 0;
42   x = abs(x);
43   y = abs(y);
44 
45   if (x < size/2 && y < size/4) {
46       if (x < size / 4) {
47         result = 1;
48       }
49       else {
50         if (x < ((size / 2) - y)) {
51           result = 1;
52         }
53       }
54   }
55   return(result);
56 }
57 
58 //
59 
add(void ** list,void * item,int position,int max_n)60 static void add(void **list, void *item, int position, int max_n) {
61   if (position < (max_n - 1)) {
62     list[position] = item;
63   }
64   else {
65     printf("add reached maximum items (%d)\n", max_n);
66     exit(1);
67   }
68 }
69 
70 //
71 
getShape(int shape_type,int size)72 extern t_shape *getShape(int shape_type, int size) {
73   size = (size * 4) + 8;
74   inShapePtr inShape = inShapes[shape_type % SHAPE_N];
75   t_point *look;
76   int possible[6][2];
77   t_line **lines = calloc(MAX_LINES, sizeof(t_line *));
78   int lines_n = 0;
79   t_shape *result = (t_shape *) calloc(1, sizeof(t_shape));
80 
81   t_point **search = (t_point **) calloc(MAX_TMP, sizeof(t_point *));
82   int search_n = 0;
83 
84   t_point **points = (t_point **) calloc(MAX_TMP, sizeof(t_point *));
85   int points_n = 0;
86 
87   int i, j, x, y;
88   t_line *line_p;
89   t_point *point_p;
90   int seen;
91   int edge_n = 0;
92 
93   look = (t_point *)calloc(1, sizeof(t_point));
94   look->x = 0;
95   look->y = 0;
96   look->id = 0;
97 
98   possible[0][0] =  1; possible[0][1] =  1;
99   possible[1][0] =  2; possible[1][1] =  0;
100   possible[2][0] =  1; possible[2][1] = -1;
101   possible[3][0] = -1; possible[3][1] = -1;
102   possible[4][0] = -2; possible[4][1] =  0;
103   possible[5][0] = -1; possible[5][1] =  1;
104 
105   add((void *) points, (void *) look, points_n++, MAX_TMP);
106 
107   while(look != NULL) {
108     //printf("looking: %dx%d\n", look->x, look->y);
109     for (i = 0; i < 6; ++i) {
110       x = look->x + possible[i][0];
111       y = look->y + possible[i][1];
112 
113       if (! (*inShape)(size, x, y)) {
114 	if (!look->is_edge) {
115 	  look->is_edge = 1;
116 	  edge_n++;
117 	}
118       }
119       else {
120         seen = 0;
121         for (j = 0; j < points_n; ++j) {
122           point_p = points[j];
123           if (point_p->x == x && point_p->y == y) {
124             seen = 1;
125             break;
126           }
127         }
128         if (!seen) {
129           point_p = (t_point *)calloc(1, sizeof(t_point));
130 	  point_p->x = x;
131 	  point_p->y = y;
132 	  point_p->id = points_n;
133 	  add((void **) search,  (void *) point_p, search_n++,  MAX_TMP);
134 	  add((void **) points, (void *) point_p, points_n++, MAX_TMP);
135         }
136 
137         // only save half the lines
138         if (i < 3) {
139 	  line_p = calloc(1, sizeof(t_line));
140 	  line_p->a = look;
141 	  line_p->b = point_p;
142 	  add((void **) lines, (void *) line_p, lines_n++, MAX_LINES);
143         }
144       }
145     }
146 
147     if (search_n == 0) {
148       look = NULL;
149       break;
150     }
151     else {
152       look = search[--search_n];
153     }
154   }
155   free(search);
156 
157   result->points   = points;
158   result->points_n = points_n;
159   result->lines    = lines;
160   result->lines_n  = lines_n;
161   result->edge_n = edge_n;
162 
163 
164 #ifndef QUIET
165   printf("Made shape with %d lines, %d points and %d edge points.\n",
166 	 lines_n,
167 	 points_n,
168 	 edge_n
169 	 );
170 #endif
171 
172   return(result);
173 }
174 
free_shape(t_shape * shape)175 extern void free_shape(t_shape *shape) {
176   int i;
177   for (i = 0; i < shape->lines_n; ++i) {
178     free(shape->lines[i]);
179   }
180   for (i = 0; i < shape->points_n; ++i) {
181     free(shape->points[i]);
182   }
183   free(shape->lines);
184   free(shape->points);
185   free(shape);
186 }
187