commit | author | age
|
0af0cf
|
1 |
#include<general.h> |
SP |
2 |
#include<cross-section.h> |
|
3 |
#include<coord.h> |
a61c00
|
4 |
#include<cairo/cairo.h> |
0af0cf
|
5 |
/** @brief Calculates cross-section of vesicle with plane. |
SP |
6 |
* |
|
7 |
* Function returns points of cross-section of vesicle with plane. Plane is described with equation $ax+by+cz+d=0$. Algorithm extracts coordinates of each vertex of a vesicle and then: |
|
8 |
* |
|
9 |
* if a distance of point to plane (given by equation $D=\frac{ax_0+by_0+cz_0+d}{\sqrt{a^2+b^2+c^2}}$, where $x_0$, $y_0$ and $z_0$ are coordinates of a given vertex) is less than maximal allowed distance between vertices {\tt sqrt(vesicle->dmax)} than vertex is a candidate for crossection calculation. |
|
10 |
* |
|
11 |
*/ |
d27c07
|
12 |
ts_coord_list *get_crossection_with_plane(ts_vesicle *vesicle,ts_double a,ts_double b,ts_double c, ts_double d){ |
0af0cf
|
13 |
|
SP |
14 |
|
ad4e70
|
15 |
ts_uint i, j,k,l; |
0af0cf
|
16 |
ts_double pp,Dsq; // distance from the plane squared |
ad4e70
|
17 |
ts_double ppn1; // distance from the plane squared of a neighbor |
0af0cf
|
18 |
ts_vertex *vtx; |
a61c00
|
19 |
ts_uint ntria=0; // number triangles |
SP |
20 |
ts_triangle *tria[2]; // list of triangles |
0af0cf
|
21 |
ts_coord_list *pts=init_coord_list(); |
d27c07
|
22 |
for(i=0;i<vesicle->vlist->n;i++){ |
0af0cf
|
23 |
vtx=vesicle->vlist->vtx[i]; |
SP |
24 |
|
|
25 |
pp=vtx->x*a+vtx->y*b+vtx->z*c+d; |
|
26 |
Dsq=pp*pp/(a*a+b*b+c*c); |
|
27 |
if(Dsq<vesicle->dmax){ |
|
28 |
for(j=0;j<vtx->neigh_no;j++){ |
a61c00
|
29 |
ppn1=vtx->neigh[j]->x*a+vtx->neigh[j]->y*b+vtx->neigh[j]->z*c+d; |
SP |
30 |
if(pp*ppn1<=0){ //the combination of vertices are good candidates for a crossection |
|
31 |
//find triangle that belongs to the two vertices |
|
32 |
ntria=0; |
|
33 |
for(k=0;k<vtx->tristar_no;k++){ |
ad4e70
|
34 |
if(vtx->tristar[k]->vertex[0]==vtx && ( vtx->tristar[k]->vertex[1]==vtx->neigh[j] || vtx->tristar[k]->vertex[2]==vtx->neigh[j]) ){ |
a61c00
|
35 |
//triangle found. |
SP |
36 |
tria[ntria]=vtx->tristar[k]; |
|
37 |
ntria++; |
|
38 |
} |
|
39 |
} |
|
40 |
// if ntria !=1 there is probably something wrong I would say... |
|
41 |
if(ntria==0) continue; |
ad4e70
|
42 |
/* if(ntria!=1) { //there should be 2 triangles. of course, all some of them will be doubled. |
a61c00
|
43 |
fprintf(stderr,"ntria=%u\n",ntria); |
ad4e70
|
44 |
fatal ("Error in mesh. 2 triangles not found",123123); |
SP |
45 |
} */ |
a61c00
|
46 |
//find the two intersections (in general) to form a intersection line |
ad4e70
|
47 |
for(l=0;l<ntria;l++){ |
SP |
48 |
//we add intersection line between two points for each of the triangles found above. |
|
49 |
add_crosssection_point(pts,a,b,c,d,tria[l]->vertex[0], tria[l]->vertex[1]); |
|
50 |
add_crosssection_point(pts,a,b,c,d,tria[l]->vertex[0], tria[l]->vertex[2]); |
|
51 |
add_crosssection_point(pts,a,b,c,d,tria[l]->vertex[1], tria[l]->vertex[2]); |
a61c00
|
52 |
|
SP |
53 |
} |
0af0cf
|
54 |
} |
SP |
55 |
} |
|
56 |
} |
|
57 |
} |
|
58 |
return pts; |
|
59 |
} |
|
60 |
|
|
61 |
|
ad4e70
|
62 |
|
SP |
63 |
ts_bool add_crosssection_point(ts_coord_list *pts, ts_double a, ts_double b, ts_double c, ts_double d, ts_vertex *vtx1, ts_vertex *vtx2){ |
|
64 |
ts_double pp=vtx1->x*a+vtx1->y*b+vtx1->z*c+d; |
|
65 |
ts_double pp2=vtx2->x*a+vtx1->y*b+vtx2->z*c+d; |
|
66 |
if(pp*pp2<=0){ |
|
67 |
ts_double u=pp/(a*(vtx1->x-vtx2->x)+b*(vtx1->y-vtx2->y)+c*(vtx1->z-vtx2->z)); |
|
68 |
add_coord(pts, vtx1->x+u*(vtx2->x - vtx1->x), |
|
69 |
vtx1->y+u*(vtx2->y - vtx1->y), |
|
70 |
vtx1->z+u*(vtx2->z - vtx1->z), |
|
71 |
TS_COORD_CARTESIAN); |
|
72 |
|
|
73 |
return TS_SUCCESS; |
|
74 |
} else { |
|
75 |
return TS_FAIL; |
|
76 |
} |
|
77 |
} |
|
78 |
|
a61c00
|
79 |
/** Saves calculated crossection as a png image */ |
SP |
80 |
ts_bool crossection_to_png(ts_coord_list *pts, char *filename){ |
|
81 |
|
|
82 |
cairo_surface_t *surface; |
|
83 |
cairo_t *cr; |
|
84 |
ts_uint i; |
ad4e70
|
85 |
surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 1800, 1800); |
a61c00
|
86 |
cr = cairo_create (surface); |
SP |
87 |
cairo_rectangle(cr, 0.0, 0.0, 1800,1800); |
|
88 |
cairo_set_source_rgb(cr, 0.3, 0.3, 0.3); |
|
89 |
cairo_fill(cr); |
|
90 |
cairo_set_line_width (cr, 5.0/30.0); |
|
91 |
cairo_translate(cr, 900,900); |
|
92 |
cairo_scale (cr, 30, 30); |
|
93 |
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); |
|
94 |
|
|
95 |
for(i=0;i<pts->n;i+=2){ |
|
96 |
cairo_move_to(cr, pts->coord[i]->e1, pts->coord[i]->e2); |
|
97 |
cairo_line_to(cr, pts->coord[i+1]->e1, pts->coord[i+1]->e2); |
|
98 |
} |
|
99 |
cairo_stroke(cr); |
|
100 |
cairo_surface_write_to_png (surface,filename); |
|
101 |
cairo_surface_finish (surface); |
|
102 |
return TS_SUCCESS; |
|
103 |
} |
ad4e70
|
104 |
|
SP |
105 |
|
|
106 |
ts_bool save_crossection_snapshot(ts_coord_list *pts, ts_uint timestepno){ |
|
107 |
char filename[255]; |
|
108 |
sprintf(filename,"timestep_%.6u.png",timestepno); |
|
109 |
crossection_to_png(pts,filename); |
|
110 |
return TS_SUCCESS; |
|
111 |
} |