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