commit | author | age
|
d7639a
|
1 |
#include<stdlib.h> |
SP |
2 |
#include<stdio.h> |
|
3 |
#include "general.h" |
|
4 |
#include "triangle.h" |
|
5 |
#include<math.h> |
|
6 |
|
bb77ca
|
7 |
/** @brief Prepares the list for triangles. |
632960
|
8 |
* @returns pointer to empty data structure for maintaining triangle list. |
bb77ca
|
9 |
* |
SP |
10 |
* Create empty list for holding the information on triangles. Triangles are |
|
11 |
* added later on with triangle_add(). |
|
12 |
* Returns pointer to the tlist datastructure it has created. This pointer must |
|
13 |
* be assigned to some variable or it will be lost. |
|
14 |
* |
|
15 |
* |
|
16 |
* Example of usage: |
|
17 |
* ts_triangle_list *tlist; |
|
18 |
* tlist=triangle_data_free(); |
|
19 |
* |
|
20 |
* Initalized data structure for holding the information on triangles. |
|
21 |
* |
|
22 |
*/ |
a2a676
|
23 |
ts_triangle_list *init_triangle_list(){ |
SP |
24 |
ts_triangle_list *tlist=(ts_triangle_list *)malloc(sizeof(ts_triangle_list)); |
d7639a
|
25 |
tlist->n = 0; |
a2a676
|
26 |
tlist->tria=NULL; |
SP |
27 |
return tlist; |
d7639a
|
28 |
} |
SP |
29 |
|
bb77ca
|
30 |
/** @brief Add the triangle to the triangle list and create necessary data |
632960
|
31 |
* structures. |
SP |
32 |
* @param *tlist is a pointer to triangle list where triangle should be created |
|
33 |
* @param *vtx1, *vtx2, *vtx3 are the three vertices defining the triangle |
|
34 |
* @returns pointer to the newly created triangle on success and NULL if |
|
35 |
* triangle could not be created. It breaks program execution if memory |
|
36 |
* allocation of triangle list can't be done. |
bb77ca
|
37 |
* |
632960
|
38 |
* Add the triangle ts_triangle to the ts_triangle_list. |
bb77ca
|
39 |
* The triangle list is resized, the ts_triangle is allocated and |
632960
|
40 |
* triangle data is zeroed. Returned pointer to newly |
SP |
41 |
* created triangle doesn't need assigning, since it is |
bb77ca
|
42 |
* referenced by triangle list. |
SP |
43 |
* |
|
44 |
* WARNING: Function can be accelerated a bit by removing the NULL checks. |
|
45 |
* However the time gained by removal doesn't justify the time spent by |
|
46 |
* debugging stupid NULL pointers. |
|
47 |
* |
|
48 |
* Example of usage: |
|
49 |
* triangle_add(tlist, vlist->vtx[1], vlist->vtx[2], vlist->vtx[3]); |
|
50 |
* |
|
51 |
* Creates a triangle with given vertices and puts it into the list. |
|
52 |
* |
|
53 |
*/ |
a2a676
|
54 |
ts_triangle *triangle_add(ts_triangle_list *tlist, ts_vertex *vtx1, ts_vertex *vtx2, ts_vertex *vtx3){ |
SP |
55 |
if(vtx1==NULL || vtx2==NULL || vtx3==NULL){ |
|
56 |
return NULL; |
|
57 |
} |
d7639a
|
58 |
tlist->n++; |
a2a676
|
59 |
tlist->tria=(ts_triangle **)realloc(tlist->tria,tlist->n*sizeof(ts_triangle *)); |
SP |
60 |
if(tlist->tria==NULL) fatal("Cannot reallocate memory for additional ts_triangle.",5); |
|
61 |
|
|
62 |
tlist->tria[tlist->n-1]=(ts_triangle *)calloc(1,sizeof(ts_triangle)); |
|
63 |
if(tlist->tria[tlist->n-1]==NULL) fatal("Cannot reallocate memory for additional ts_triangle.",5); |
|
64 |
|
d7639a
|
65 |
//NOW insert vertices! |
a2a676
|
66 |
tlist->tria[tlist->n - 1]->idx=tlist->n-1; |
41a035
|
67 |
tlist->tria[tlist->n - 1]->vertex[0]=vtx1; |
SP |
68 |
tlist->tria[tlist->n - 1]->vertex[1]=vtx2; |
|
69 |
tlist->tria[tlist->n - 1]->vertex[2]=vtx3; |
a2a676
|
70 |
return tlist->tria[tlist->n-1]; |
d7639a
|
71 |
} |
SP |
72 |
|
bb77ca
|
73 |
/** @brief Add the neigbour to triangles. |
632960
|
74 |
* @param *tria is a first triangle. |
SP |
75 |
* @param *ntria is a second triangle. |
|
76 |
* @returns TS_SUCCES on sucessful adition to the list, TS_FAIL if triangles |
|
77 |
* are NULL and breaks execution FATALY if memory allocation error occurs. |
bb77ca
|
78 |
* |
SP |
79 |
* Add the neigbour to the list of neighbouring triangles. The |
632960
|
80 |
* neighbouring triangles are those, who share two vertices and corresponding |
SP |
81 |
* bond. Function resizes |
bb77ca
|
82 |
* the list and adds the pointer to neighbour. It receives two arguments of |
dac2e5
|
83 |
* ts_triangle type. It then adds second triangle to the list of first |
SP |
84 |
* triangle, but not the opposite. Upon |
bb77ca
|
85 |
* success it returns TS_SUCCESS, upon detecting NULL pointers |
SP |
86 |
* returns TS_FAIL and it FATALY ends when the data structure |
|
87 |
* cannot be resized. |
|
88 |
* |
|
89 |
* |
|
90 |
* WARNING: Function can be accelerated a bit by removing the NULL checks. |
|
91 |
* However the time gained by removal doesn't justify the time spent by |
|
92 |
* debugging stupid NULL pointers. |
|
93 |
* |
|
94 |
* Example of usage: |
632960
|
95 |
* triangle_add_neighbour(tlist->tria[3], tlist->tria[4]); |
bb77ca
|
96 |
* |
632960
|
97 |
* Triangle 4 is a neighbour of triangle 3, but (strangely) not the |
SP |
98 |
* oposite. The function should be called again with the changed order of |
|
99 |
* triangles to make neighbourship mutual. |
bb77ca
|
100 |
* |
SP |
101 |
*/ |
d7639a
|
102 |
|
SP |
103 |
ts_bool triangle_add_neighbour(ts_triangle *tria, ts_triangle *ntria){ |
a2a676
|
104 |
if(tria==NULL || ntria==NULL) return TS_FAIL; |
41a035
|
105 |
tria->neigh_no++; |
SP |
106 |
tria->neigh=realloc(tria->neigh,tria->neigh_no*sizeof(ts_triangle *)); |
|
107 |
if(tria->neigh == NULL) |
d7639a
|
108 |
fatal("Reallocation of memory failed during insertion of triangle neighbour in triangle_add_neighbour",3); |
632960
|
109 |
tria->neigh[tria->neigh_no-1]=ntria; |
d7639a
|
110 |
return TS_SUCCESS; |
SP |
111 |
} |
|
112 |
|
bb77ca
|
113 |
/** @brief Remove the neigbours from triangle. |
632960
|
114 |
* @param *tria is a first triangle. |
SP |
115 |
* @param *ntria is neighbouring triangle. |
|
116 |
* @returns TS_SUCCESS on successful removal, TS_FAIL if triangles are not |
|
117 |
* neighbours and it breaks program execution FATALY if memory allocation |
|
118 |
* problem occurs. |
bb77ca
|
119 |
* |
SP |
120 |
* Removes the neigbour from the list of neighbouring triangles. The |
632960
|
121 |
* neighbouring triangles are those, who share two vertices and corresponding |
SP |
122 |
* bond. Function resizes |
bb77ca
|
123 |
* the list and deletes the pointer to neighbour. It receives two arguments of |
632960
|
124 |
* ts_triangle type. It then mutually removes triangles from eachouther |
SP |
125 |
* neighbour list. Upon |
bb77ca
|
126 |
* success it returns TS_SUCCESS, upon failure to find the triangle in the |
632960
|
127 |
* neighbour list returns TS_FAIL. It FATALY breaks program execution when the datastructure |
SP |
128 |
* cannot be resized due to memory constrain problems. |
bb77ca
|
129 |
* |
SP |
130 |
* WARNING: The function doesn't check whether the pointer is NULL or invalid. It is the |
|
131 |
* job of programmer to make sure the pointer is valid. |
|
132 |
* |
|
133 |
* WARNING: Function is slow. Do not use it often! |
|
134 |
* |
|
135 |
* Example of usage: |
|
136 |
* triangle_remove_neighbour(tlist->tria[3], tlist->tria[4]); |
|
137 |
* |
|
138 |
* Triangles 3 and 4 are not neighbours anymore. |
|
139 |
* |
|
140 |
*/ |
d7639a
|
141 |
ts_bool triangle_remove_neighbour(ts_triangle *tria, ts_triangle *ntria){ |
a2a676
|
142 |
ts_uint i,j=0; |
SP |
143 |
if(tria==NULL || ntria==NULL) return TS_FAIL; |
|
144 |
|
41a035
|
145 |
for(i=0;i<tria->neigh_no;i++){ |
SP |
146 |
if(tria->neigh[i]!=ntria){ |
|
147 |
tria->neigh[j]=tria->neigh[i]; |
d7639a
|
148 |
j++; |
SP |
149 |
} |
|
150 |
} |
a2a676
|
151 |
if(j==i) { |
SP |
152 |
return TS_FAIL; |
|
153 |
} |
41a035
|
154 |
tria->neigh_no--; |
SP |
155 |
tria->neigh=(ts_triangle **)realloc(tria->neigh,tria->neigh_no*sizeof(ts_triangle *)); |
|
156 |
if(tria->neigh == NULL){ |
2870ab
|
157 |
fprintf(stderr,"Ooops: tria->neigh_no=%d\n",tria->neigh_no); |
a2a676
|
158 |
fatal("Reallocation of memory failed during removal of vertex neighbour in triangle_remove_neighbour",100); |
SP |
159 |
} |
|
160 |
/* we repeat the procedure for neighbour */ |
e19e79
|
161 |
j=0; |
41a035
|
162 |
for(i=0;i<ntria->neigh_no;i++){ |
SP |
163 |
if(ntria->neigh[i]!=tria){ |
|
164 |
ntria->neigh[j]=ntria->neigh[i]; |
a2a676
|
165 |
j++; |
SP |
166 |
} |
|
167 |
} |
|
168 |
if(j==i) { |
|
169 |
return TS_FAIL; |
|
170 |
} |
41a035
|
171 |
ntria->neigh_no--; |
SP |
172 |
ntria->neigh=(ts_triangle **)realloc(ntria->neigh,ntria->neigh_no*sizeof(ts_triangle *)); |
|
173 |
if(ntria->neigh == NULL){ |
2870ab
|
174 |
fprintf(stderr,"Ooops: ntria->neigh_no=%d\n",ntria->neigh_no); |
a2a676
|
175 |
fatal("Reallocation of memory failed during removal of vertex neighbour in triangle_remove_neighbour",100); |
SP |
176 |
} |
d7639a
|
177 |
return TS_SUCCESS; |
SP |
178 |
} |
|
179 |
|
bb77ca
|
180 |
|
632960
|
181 |
/** @brief Calculates normal vector of the triangle, its corresponding area and volume. |
SP |
182 |
* @param *tria is a triangle pointer for which normal, area and volume is |
|
183 |
* to be calculated. |
|
184 |
* @returns TS_SUCCESS on success. (always) |
bb77ca
|
185 |
* |
SP |
186 |
* Calculate normal vector of the triangle (xnorm, ynorm and znorm) and stores |
632960
|
187 |
* information. At the same time |
SP |
188 |
* triangle area is determined, since we already have the normal and volume of |
|
189 |
* triangular pyramid with given triangle as a base and vesicle centroid as a |
|
190 |
* tip. |
bb77ca
|
191 |
* |
SP |
192 |
* Function receives one argument of type ts_triangle. It should be corectly |
632960
|
193 |
* initialized. The |
SP |
194 |
* result is stored in triangle->xnorm, triangle->ynorm, triangle->znorm. |
|
195 |
* Area and volume are stored into triangle->area and triangle->volume. |
|
196 |
* Returns TS_SUCCESS on completion. |
bb77ca
|
197 |
* |
632960
|
198 |
* NOTE: Function uses math.h library. Function pow implementation is selected |
SP |
199 |
* accordind to the used TS_DOUBLE_* definition set in general.h, so it should |
|
200 |
* be compatible with any type of floating point precision. |
bb77ca
|
201 |
* |
SP |
202 |
* Example of usage: |
|
203 |
* triangle_normal_vector(tlist->tria[3]); |
|
204 |
* |
|
205 |
* Computes normals and stores information into tlist->tria[3]->xnorm, |
632960
|
206 |
* tlist->tria[3]->ynorm, tlist->tria[3]->znorm tlist->tria[3]->area and |
SP |
207 |
* tlist->tria[3]->volume. |
bb77ca
|
208 |
* |
SP |
209 |
*/ |
d7639a
|
210 |
ts_bool triangle_normal_vector(ts_triangle *tria){ |
SP |
211 |
ts_double x21,x31,y21,y31,z21,z31,xden; |
8f6a69
|
212 |
x21=tria->vertex[1]->x - tria->vertex[0]->x; |
SP |
213 |
x31=tria->vertex[2]->x - tria->vertex[0]->x; |
|
214 |
y21=tria->vertex[1]->y - tria->vertex[0]->y; |
|
215 |
y31=tria->vertex[2]->y - tria->vertex[0]->y; |
|
216 |
z21=tria->vertex[1]->z - tria->vertex[0]->z; |
|
217 |
z31=tria->vertex[2]->z - tria->vertex[0]->z; |
d7639a
|
218 |
|
41a035
|
219 |
tria->xnorm=y21*z31 - z21*y31; |
SP |
220 |
tria->ynorm=z21*x31 - x21*z31; |
|
221 |
tria->znorm=x21*y31 - y21*x31; |
|
222 |
xden=tria->xnorm*tria->xnorm + |
|
223 |
tria->ynorm*tria->ynorm + |
|
224 |
tria->znorm*tria->znorm; |
d7639a
|
225 |
#ifdef TS_DOUBLE_DOUBLE |
SP |
226 |
xden=sqrt(xden); |
|
227 |
#endif |
|
228 |
#ifdef TS_DOUBLE_FLOAT |
|
229 |
xden=sqrtf(xden); |
|
230 |
#endif |
|
231 |
#ifdef TS_DOUBLE_LONGDOUBLE |
|
232 |
xden=sqrtl(xden); |
|
233 |
#endif |
41a035
|
234 |
tria->xnorm=tria->xnorm/xden; |
SP |
235 |
tria->ynorm=tria->ynorm/xden; |
|
236 |
tria->znorm=tria->znorm/xden; |
c9d07c
|
237 |
|
SP |
238 |
/* Here it is an excellent point to recalculate volume of the triangle and |
|
239 |
* store it into datastructure. Volume is required at least by constant volume |
|
240 |
* calculation of vertex move and bondflip and spherical harmonics. */ |
|
241 |
tria->volume=(tria->vertex[0]->x+ tria->vertex[1]->x + tria->vertex[2]->x) * tria->xnorm + |
|
242 |
(tria->vertex[0]->y+ tria->vertex[1]->y + tria->vertex[2]->y) * tria->ynorm + |
|
243 |
(tria->vertex[0]->z+ tria->vertex[1]->z + tria->vertex[2]->z) * tria->znorm; |
|
244 |
tria->volume=-xden*tria->volume/18.0; |
|
245 |
/* Also, area can be calculated in each triangle */ |
|
246 |
tria->area=xden/2; |
|
247 |
|
|
248 |
|
d7639a
|
249 |
return TS_SUCCESS; |
SP |
250 |
} |
|
251 |
|
bb77ca
|
252 |
/** @brief Frees the memory allocated for data structure of triangle list |
632960
|
253 |
* @param *tlist is a pointer to datastructure triangle list to be freed. |
SP |
254 |
* @returns TS_SUCCESS on success (always). |
bb77ca
|
255 |
* |
SP |
256 |
* Function frees the memory of ts_triangle_list previously allocated. It |
|
257 |
* accepts one argument, the address of data structure. It destroys all |
|
258 |
* ts_triangle's in the list with underlying data (by calling |
|
259 |
* triangle_data_free()), and the list itself. |
|
260 |
* |
|
261 |
* Should be used eveytime the deletion of triangle list (created by |
|
262 |
* init_triangle_list() and altered by add_triangle() or remove_triangle()) is desired. |
|
263 |
* |
|
264 |
* WARNING: The function doesn't check whether the pointer is NULL or invalid. It is the |
|
265 |
* job of programmer to make sure the pointer is valid. |
|
266 |
* |
|
267 |
* WARNING: Careful when destroying triangle lists. There could be pointers to |
|
268 |
* that information remaining in structures like vertex_data. This pointers |
|
269 |
* will be rendered invalid by this operation and should not be used anymore. |
|
270 |
* |
|
271 |
* Example of usage: |
|
272 |
* triangle_list_free(tlist); |
|
273 |
* |
|
274 |
* Clears all the information on triangles. |
|
275 |
* |
|
276 |
*/ |
d7639a
|
277 |
ts_bool triangle_list_free(ts_triangle_list *tlist){ |
a2a676
|
278 |
ts_uint i; |
d7639a
|
279 |
for(i=0;i<tlist->n;i++){ |
41a035
|
280 |
if(tlist->tria[i]->neigh!=NULL) free(tlist->tria[i]->neigh); |
a2a676
|
281 |
free(tlist->tria[i]); |
d7639a
|
282 |
} |
a2a676
|
283 |
free(tlist->tria); |
SP |
284 |
free(tlist); |
d7639a
|
285 |
return TS_SUCCESS; |
SP |
286 |
} |
|
287 |
|