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 |
|
a61c00
|
15 |
ts_uint i, j,k; |
0af0cf
|
16 |
ts_double pp,Dsq; // distance from the plane squared |
a61c00
|
17 |
ts_double ppn1,ppn2; // distance from the plane squared of a neighbor |
0af0cf
|
18 |
ts_double u; //factor to scale vector from first vector to the second to get intersection |
SP |
19 |
ts_vertex *vtx; |
a61c00
|
20 |
ts_uint ntria=0; // number triangles |
SP |
21 |
ts_uint cnt=0; |
|
22 |
ts_triangle *tria[2]; // list of triangles |
0af0cf
|
23 |
ts_coord_list *pts=init_coord_list(); |
d27c07
|
24 |
for(i=0;i<vesicle->vlist->n;i++){ |
0af0cf
|
25 |
vtx=vesicle->vlist->vtx[i]; |
SP |
26 |
|
|
27 |
pp=vtx->x*a+vtx->y*b+vtx->z*c+d; |
|
28 |
Dsq=pp*pp/(a*a+b*b+c*c); |
|
29 |
if(Dsq<vesicle->dmax){ |
|
30 |
for(j=0;j<vtx->neigh_no;j++){ |
a61c00
|
31 |
ppn1=vtx->neigh[j]->x*a+vtx->neigh[j]->y*b+vtx->neigh[j]->z*c+d; |
SP |
32 |
if(pp*ppn1<=0){ //the combination of vertices are good candidates for a crossection |
|
33 |
/* u=pp/(a*(vtx->x-vtx->neigh[j]->x)+b*(vtx->y-vtx->neigh[j]->y)+c*(vtx->z-vtx->neigh[j]->z)); |
d27c07
|
34 |
add_coord(pts, vtx->x+u*(vtx->neigh[j]->x - vtx->x), |
SP |
35 |
vtx->y+u*(vtx->neigh[j]->y - vtx->y), |
|
36 |
vtx->z+u*(vtx->neigh[j]->z - vtx->z), |
0af0cf
|
37 |
TS_COORD_CARTESIAN); |
a61c00
|
38 |
|
SP |
39 |
*/ |
|
40 |
//find triangle that belongs to the two vertices |
|
41 |
cnt=0; |
|
42 |
ntria=0; |
|
43 |
for(k=0;k<vtx->tristar_no;k++){ |
|
44 |
if(vtx->tristar[k]->vertex[1]==vtx->neigh[j] && vtx->tristar[k]->vertex[0]==vtx){ |
|
45 |
//triangle found. |
|
46 |
tria[ntria]=vtx->tristar[k]; |
|
47 |
ntria++; |
|
48 |
} |
|
49 |
} |
|
50 |
// if ntria !=1 there is probably something wrong I would say... |
|
51 |
if(ntria==0) continue; |
|
52 |
if(ntria!=1) { |
|
53 |
fprintf(stderr,"ntria=%u\n",ntria); |
|
54 |
fatal ("Error in mesh. 1 triangle not found",123123); |
|
55 |
} |
|
56 |
//find the two intersections (in general) to form a intersection line |
|
57 |
/* we dont know which vertex is which, so we need to recalculate all previously calculated values*/ |
|
58 |
pp=vtx->x*a+vtx->y*b+vtx->z*c+d; |
|
59 |
ppn1=vtx->neigh[j]->x*a+vtx->neigh[j]->y*b+vtx->neigh[j]->z*c+d; |
|
60 |
|
|
61 |
u=pp/(a*(vtx->x-vtx->neigh[j]->x)+b*(vtx->y-vtx->neigh[j]->y)+c*(vtx->z-vtx->neigh[j]->z)); |
|
62 |
add_coord(pts, vtx->x+u*(vtx->neigh[j]->x - vtx->x), |
|
63 |
vtx->y+u*(vtx->neigh[j]->y - vtx->y), |
|
64 |
vtx->z+u*(vtx->neigh[j]->z - vtx->z), |
|
65 |
TS_COORD_CARTESIAN); |
|
66 |
ppn2=tria[0]->vertex[2]->x*a+tria[0]->vertex[2]->y*b+tria[0]->vertex[2]->z*c+d; |
|
67 |
cnt++; |
|
68 |
//two more tries to find anothen pair of vertices, one above and one below the intersection plane */ |
|
69 |
if(pp*ppn2<=0) { |
|
70 |
u=pp/(a*(vtx->x-tria[0]->vertex[2]->x)+b*(vtx->y-tria[0]->vertex[2]->y)+c*(vtx->z-tria[0]->vertex[2]->z)); |
|
71 |
add_coord(pts, vtx->x+u*(tria[0]->vertex[2]->x - vtx->x), |
|
72 |
vtx->y+u*(tria[0]->vertex[2]->y - vtx->y), |
|
73 |
vtx->z+u*(tria[0]->vertex[2]->z - vtx->z), |
|
74 |
TS_COORD_CARTESIAN); |
|
75 |
cnt++; |
|
76 |
} |
|
77 |
|
|
78 |
if(ppn2*ppn1<=0) { |
|
79 |
u=ppn1/(a*(vtx->neigh[j]->x-tria[0]->vertex[2]->x)+b*(vtx->neigh[j]->y-tria[0]->vertex[2]->y)+c*(vtx->neigh[j]->z-tria[0]->vertex[2]->z)); |
|
80 |
add_coord(pts, vtx->neigh[j]->x+u*(tria[0]->vertex[2]->x - vtx->neigh[j]->x), |
|
81 |
vtx->neigh[j]->y+u*(tria[0]->vertex[2]->y - vtx->neigh[j]->y), |
|
82 |
vtx->neigh[j]->z+u*(tria[0]->vertex[2]->z - vtx->neigh[j]->z), |
|
83 |
TS_COORD_CARTESIAN); |
|
84 |
cnt++; |
|
85 |
|
|
86 |
} |
|
87 |
|
|
88 |
|
|
89 |
if(cnt!=2){ |
|
90 |
fprintf(stderr,"Hey, cnt=%u",cnt); |
|
91 |
} |
0af0cf
|
92 |
} |
SP |
93 |
} |
|
94 |
} |
|
95 |
} |
|
96 |
return pts; |
|
97 |
} |
|
98 |
|
|
99 |
|
a61c00
|
100 |
/** Saves calculated crossection as a png image */ |
SP |
101 |
ts_bool crossection_to_png(ts_coord_list *pts, char *filename){ |
|
102 |
|
|
103 |
cairo_surface_t *surface; |
|
104 |
cairo_t *cr; |
|
105 |
ts_uint i; |
|
106 |
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1800, 1800); |
|
107 |
cr = cairo_create (surface); |
|
108 |
cairo_rectangle(cr, 0.0, 0.0, 1800,1800); |
|
109 |
cairo_set_source_rgb(cr, 0.3, 0.3, 0.3); |
|
110 |
cairo_fill(cr); |
|
111 |
cairo_set_line_width (cr, 5.0/30.0); |
|
112 |
cairo_translate(cr, 900,900); |
|
113 |
cairo_scale (cr, 30, 30); |
|
114 |
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); |
|
115 |
|
|
116 |
for(i=0;i<pts->n;i+=2){ |
|
117 |
cairo_move_to(cr, pts->coord[i]->e1, pts->coord[i]->e2); |
|
118 |
cairo_line_to(cr, pts->coord[i+1]->e1, pts->coord[i+1]->e2); |
|
119 |
} |
|
120 |
cairo_stroke(cr); |
|
121 |
cairo_surface_write_to_png (surface,filename); |
|
122 |
cairo_surface_finish (surface); |
|
123 |
return TS_SUCCESS; |
|
124 |
} |