Trisurf Monte Carlo simulator
Samo Penic
2015-10-06 6c3bb91fea92c5013507bdf4f5ac49e889e213ff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include<general.h>
#include<cross-section.h>
#include<coord.h>
#include<cairo/cairo.h>
#include<stdint.h>
/** @brief Calculates cross-section of vesicle with plane.
 *
 * 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:
 *
 * 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.
 *
 */
ts_coord_list *get_crossection_with_plane(ts_vesicle *vesicle,ts_double a,ts_double b,ts_double c, ts_double d){
 
 
    ts_uint i, j,k,l;
    ts_double pp,Dsq; // distance from the plane squared
    ts_double ppn1; // distance from the plane squared of a neighbor
    ts_vertex *vtx;
    ts_uint ntria=0; // number triangles
    ts_triangle *tria[2]; // list of triangles
    ts_coord_list *pts=init_coord_list();
    for(i=0;i<vesicle->vlist->n;i++){
        vtx=vesicle->vlist->vtx[i];
 
        pp=vtx->x*a+vtx->y*b+vtx->z*c+d;
        Dsq=pp*pp/(a*a+b*b+c*c);
        if(Dsq<vesicle->dmax){
            for(j=0;j<vtx->neigh_no;j++){
                ppn1=vtx->neigh[j]->x*a+vtx->neigh[j]->y*b+vtx->neigh[j]->z*c+d;
                if(pp*ppn1<=0.0){ //the combination of vertices are good candidates for a crossection
                    //find triangle that belongs to the two vertices
                    ntria=0;
                    for(k=0;k<vtx->tristar_no;k++){
                        if(vtx->tristar[k]->vertex[0]==vtx && ( vtx->tristar[k]->vertex[1]==vtx->neigh[j] || vtx->tristar[k]->vertex[2]==vtx->neigh[j]) ){ 
                            //triangle found.
                            tria[ntria]=vtx->tristar[k];
                            ntria++;
                        }
                    }
                    if(ntria==0) continue; // no need to continue
                    //find the two intersections (in general) to form a intersection line
                    for(l=0;l<ntria;l++){
                    //we add intersection line between two points for each of the triangles found above.
                        add_crosssection_point(pts,a,b,c,d,tria[l]->vertex[0], tria[l]->vertex[1]);
                        add_crosssection_point(pts,a,b,c,d,tria[l]->vertex[0], tria[l]->vertex[2]);
                        add_crosssection_point(pts,a,b,c,d,tria[l]->vertex[1], tria[l]->vertex[2]);
 
                    }
                }
            }
        }
    }
    return pts;
}
 
 
 
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){
    ts_double pp=vtx1->x*a+vtx1->y*b+vtx1->z*c+d;
    ts_double pp2=vtx2->x*a+vtx1->y*b+vtx2->z*c+d;
    if(pp*pp2<=0.0){
    ts_double u=pp/(a*(vtx1->x-vtx2->x)+b*(vtx1->y-vtx2->y)+c*(vtx1->z-vtx2->z));
    add_coord(pts, vtx1->x+u*(vtx2->x - vtx1->x),
        vtx1->y+u*(vtx2->y - vtx1->y),        
        vtx1->z+u*(vtx2->z - vtx1->z),
        TS_COORD_CARTESIAN);
    
    return TS_SUCCESS;
    } else {
    return TS_FAIL;
    }
}
 
/** Saves calculated crossection as a png image */
ts_bool crossection_to_png(ts_coord_list *pts, char *filename){
 
    cairo_surface_t *surface;
    cairo_t *cr;
    ts_uint i;
    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 768, 576);
    cr = cairo_create (surface);
    cairo_rectangle(cr, 0.0, 0.0, 768,576);
    cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
    cairo_fill(cr);
    cairo_set_line_width (cr, 2.0/8.0);
    cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
    cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); 
    cairo_translate(cr, 380,250);
    cairo_scale (cr, 8.0, 8.0);
    cairo_set_source_rgb (cr, 0.3, 0.3, 0.3);
 
    for(i=0;i<pts->n;i+=2){
        cairo_move_to(cr, pts->coord[i]->e1, pts->coord[i]->e2);
        cairo_line_to(cr, pts->coord[i+1]->e1, pts->coord[i+1]->e2);
    }
    cairo_stroke(cr);
    cairo_surface_write_to_png (surface,filename);
    append_to_isak_program_raw(surface,"experimental.img");
    cairo_surface_finish (surface);    
    return TS_SUCCESS;
}
 
 
ts_bool save_crossection_snapshot(ts_coord_list *pts, ts_uint timestepno){
    char filename[255];
        sprintf(filename,"timestep_%.6u.png",timestepno);
    crossection_to_png(pts,filename);
    return TS_SUCCESS;
}
 
ts_bool append_to_isak_program_raw(cairo_surface_t *surface, char *filename){
    
    unsigned char *d=cairo_image_surface_get_data(surface);
    int w=cairo_image_surface_get_width(surface);
    int h=cairo_image_surface_get_height(surface);
    int s=cairo_image_surface_get_stride(surface);
    int i,j;
    FILE *fd=fopen(filename, "a+");
 
    uint32_t *pixelptr; 
    uint32_t my_pixel;
    uint8_t pixel_channel;
//       red = (pixel[8] >> 16) & 0xFF;
 
 
 
       fwrite (&w,sizeof(uint32_t),1,fd);
       fwrite (&h,sizeof(uint32_t),1,fd);
       fwrite (&w,sizeof(uint32_t),1,fd);//time!
    for(i=0;i<h;i++){
        for(j=0;j<w;j++){
            pixelptr=(uint32_t *)(d + i * s);
            my_pixel = pixelptr[j];
            pixel_channel=(my_pixel>>16)&0xFF;
            fwrite(&pixel_channel,sizeof(uint8_t), 1,fd);
        }
    }
    fclose(fd);
    return TS_SUCCESS;
}
 
/*ts_bool init_isak_program_raw_output_file(ts_uint w, ts_uint h, char *filename){
 
 
}*/