Trisurf Monte Carlo simulator
Samo Penic
2012-06-07 eb86057daf38a5964f0dc570243b8e60d299f2ac
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);
41a035 60   //      tlist->tria[tlist->n-1]->data=(ts_triangle_data *)calloc(1,sizeof(ts_triangle_data));
a2a676 61
d7639a 62         //NOW insert vertices!
a2a676 63         tlist->tria[tlist->n - 1]->idx=tlist->n-1;
41a035 64         tlist->tria[tlist->n - 1]->vertex[0]=vtx1;
SP 65         tlist->tria[tlist->n - 1]->vertex[1]=vtx2;
66         tlist->tria[tlist->n - 1]->vertex[2]=vtx3;
a2a676 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
dac2e5 75   * ts_triangle type. It then adds second triangle to the list of first
SP 76   * triangle, but not the opposite. Upon
bb77ca 77   * success it returns TS_SUCCESS, upon detecting NULL pointers 
SP 78   * returns TS_FAIL and it FATALY ends when the data structure
79   * cannot be resized.
80   *
81   *
82   * WARNING: Function can be accelerated a bit by removing the NULL checks.
83   * However the time gained by removal doesn't justify the time spent by
84   * debugging stupid NULL pointers.
85   *
86   * Example of usage:
87   *        triangle_remove_neighbour(tlist->tria[3], tlist->tria[4]);
88   *
89   *        Triangles 3 and 4 are not neighbours anymore.
90   *        
91   */
d7639a 92
SP 93 ts_bool triangle_add_neighbour(ts_triangle *tria, ts_triangle *ntria){
a2a676 94     if(tria==NULL || ntria==NULL) return TS_FAIL;
SP 95 /*TODO: check if the neighbour already exists! Now there is no such check
96  * because of the performance issue. */
41a035 97     tria->neigh_no++;
SP 98     tria->neigh=realloc(tria->neigh,tria->neigh_no*sizeof(ts_triangle *));
99     if(tria->neigh == NULL)
d7639a 100             fatal("Reallocation of memory failed during insertion of triangle neighbour in triangle_add_neighbour",3);
41a035 101     tria->neigh[tria->neigh_no-1]=ntria;
3131dc 102   
SP 103  
a2a676 104 /* we repeat the procedure for the neighbour */  
3131dc 105 /*    ntria->data->neigh_no++;
a2a676 106     ntria->data->neigh=realloc(ntria->data->neigh,ntria->data->neigh_no*sizeof(ts_triangle *));
SP 107     if(ntria->data->neigh == NULL)
108             fatal("Reallocation of memory failed during insertion of triangle neighbour in triangle_add_neighbour",3);
109     ntria->data->neigh[ntria->data->neigh_no-1]=tria;
3131dc 110 */
d7639a 111     return TS_SUCCESS;
SP 112 }
113
bb77ca 114 /** @brief Remove the neigbours from triangle.
SP 115   *
116   * Removes the neigbour from the list of neighbouring triangles. The
117   * neighbouring triangles are those, who share two vertices. Function resizes
118   * the list and deletes the pointer to neighbour. It receives two arguments of
119   * ts_triangle type. It then removes eachother form eachother's list. Upon
120   * success it returns TS_SUCCESS, upon failure to find the triangle in the
121   * neighbour list returns TS_FAIL and it FATALY ends when the datastructure
122   * cannot be resized.
123   *
124   * WARNING: The function doesn't check whether the pointer is NULL or invalid. It is the
125   * job of programmer to make sure the pointer is valid.
126   *
127   * WARNING: Function is slow. Do not use it often!
128   *
129   * Example of usage:
130   *        triangle_remove_neighbour(tlist->tria[3], tlist->tria[4]);
131   *
132   *        Triangles 3 and 4 are not neighbours anymore.
133   *        
134   */
d7639a 135 ts_bool triangle_remove_neighbour(ts_triangle *tria, ts_triangle *ntria){
a2a676 136     ts_uint i,j=0; 
SP 137     if(tria==NULL || ntria==NULL) return TS_FAIL;
138
41a035 139     for(i=0;i<tria->neigh_no;i++){
SP 140         if(tria->neigh[i]!=ntria){
141             tria->neigh[j]=tria->neigh[i];
d7639a 142             j++;
SP 143         } 
144     }
a2a676 145     if(j==i) {
SP 146         return TS_FAIL; 
147         //fatal("In triangle_remove_neighbour: Specified neighbour does not exist for given triangle",3);
148     }
41a035 149     tria->neigh_no--;
SP 150     tria->neigh=(ts_triangle **)realloc(tria->neigh,tria->neigh_no*sizeof(ts_triangle *));
151     if(tria->neigh == NULL){
a2a676 152         fatal("Reallocation of memory failed during removal of vertex neighbour in triangle_remove_neighbour",100);
SP 153     }
154 /* we repeat the procedure for neighbour */
41a035 155     for(i=0;i<ntria->neigh_no;i++){
SP 156         if(ntria->neigh[i]!=tria){
157             ntria->neigh[j]=ntria->neigh[i];
a2a676 158             j++;
SP 159         } 
160     }
161     if(j==i) {
162         return TS_FAIL; 
163         //fatal("In triangle_remove_neighbour: Specified neighbour does not exist for given triangle",3);
164     }
41a035 165     ntria->neigh_no--;
SP 166     ntria->neigh=(ts_triangle **)realloc(ntria->neigh,ntria->neigh_no*sizeof(ts_triangle *));
167     if(ntria->neigh == NULL){
a2a676 168         fatal("Reallocation of memory failed during removal of vertex neighbour in triangle_remove_neighbour",100);
SP 169     }
d7639a 170     return TS_SUCCESS;
SP 171 }
172
bb77ca 173
SP 174 /** @brief Calculates normal vector of the triangle.
175
176   *
177   * Calculate normal vector of the triangle (xnorm, ynorm and znorm) and stores
178   * information in underlying ts_triangle_data data_structure.
179   *
180   * Function receives one argument of type ts_triangle. It should be corectly
181   * initialized with underlying data structure of type ts_triangle_data. the
182   * result is stored in triangle->data->xnorm, triangle->data->ynorm,
183   * triangle->data->znorm. Returns TS_SUCCESS on completion. 
184   *
185   * NOTE: Function uses math.h library. pow function implementation is selected
186   * accordind to the setting in genreal.h
187   *
188   * Example of usage:
189   *        triangle_normal_vector(tlist->tria[3]);
190   *
191   *        Computes normals and stores information into tlist->tria[3]->xnorm,
192   *        tlist->tria[3]->ynorm, tlist->tria[3]->znorm.
193   *        
194   */
d7639a 195 ts_bool triangle_normal_vector(ts_triangle *tria){
SP 196     ts_double x21,x31,y21,y31,z21,z31,xden;
8f6a69 197     x21=tria->vertex[1]->x - tria->vertex[0]->x;
SP 198     x31=tria->vertex[2]->x - tria->vertex[0]->x;
199     y21=tria->vertex[1]->y - tria->vertex[0]->y;
200     y31=tria->vertex[2]->y - tria->vertex[0]->y;
201     z21=tria->vertex[1]->z - tria->vertex[0]->z;
202     z31=tria->vertex[2]->z - tria->vertex[0]->z;
d7639a 203
41a035 204     tria->xnorm=y21*z31 - z21*y31;
SP 205     tria->ynorm=z21*x31 - x21*z31;
206     tria->znorm=x21*y31 - y21*x31;
207     xden=tria->xnorm*tria->xnorm +
208          tria->ynorm*tria->ynorm + 
209          tria->znorm*tria->znorm;
d7639a 210 #ifdef TS_DOUBLE_DOUBLE
SP 211     xden=sqrt(xden);
212 #endif
213 #ifdef TS_DOUBLE_FLOAT
214     xden=sqrtf(xden);
215 #endif
216 #ifdef TS_DOUBLE_LONGDOUBLE
217     xden=sqrtl(xden);
218 #endif
41a035 219     tria->xnorm=tria->xnorm/xden;
SP 220     tria->ynorm=tria->ynorm/xden;
221     tria->znorm=tria->znorm/xden;    
d7639a 222     return TS_SUCCESS;
SP 223 }
224
225
bb77ca 226
SP 227
228
d7639a 229
bb77ca 230 /** @brief Frees the memory allocated for data structure of triangle list
SP 231  * (ts_triangle_list)
232   *
233   * Function frees the memory of ts_triangle_list previously allocated. It
234   * accepts one argument, the address of data structure. It destroys all
235   * ts_triangle's in the list with underlying data (by calling
236   * triangle_data_free()), and the list itself.
237   *
238   * Should be used eveytime the deletion of triangle list (created by
239   * init_triangle_list() and altered by add_triangle() or remove_triangle()) is desired.
240   *
241   * WARNING: The function doesn't check whether the pointer is NULL or invalid. It is the
242   * job of programmer to make sure the pointer is valid.
243   *
244   * WARNING: Careful when destroying triangle lists. There could be pointers to
245   * that information remaining in structures like vertex_data. This pointers
246   * will be rendered invalid by this operation and should not be used anymore.
247   *
248   * Example of usage:
249   *        triangle_list_free(tlist);
250   *
251   *        Clears all the information on triangles.
252   *        
253   */
d7639a 254 ts_bool triangle_list_free(ts_triangle_list *tlist){
a2a676 255     ts_uint i;
d7639a 256     for(i=0;i<tlist->n;i++){
41a035 257         if(tlist->tria[i]->neigh!=NULL) free(tlist->tria[i]->neigh);
a2a676 258         free(tlist->tria[i]);
d7639a 259     }
a2a676 260     free(tlist->tria);
SP 261     free(tlist);  
d7639a 262     return TS_SUCCESS;
SP 263 }
264