#include #include #include #include #include /** @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;ivlist->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(Dsqdmax){ for(j=0;jneigh_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;ktristar_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;lvertex[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;in;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>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){ }*/