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