void slice_sphere (struct msscene *ms, struct surface *current_surface, double fine_pixel, struct face *fac) { int k, j; double yinc, y, rad, fsgn; double cir_center[3], cir_axis[3]; char message[MAXLINE]; struct leaf *lf; struct circle *cir; struct variety *vty; struct cept *ex; vty = fac -> vty; if (vty -> type != SPHERE) { ex = new_cept (ENUM_ERROR, INVALID_VALUE, FATAL_SEVERITY); add_function (ex, "slice_sphere"); add_source (ex, "msrender.c"); add_long (ex, "variety type", (long) vty -> type); return; } /* check versus window */ for (k = 0; k < 3; k++) { if (vty -> center[k] + vty -> radii[0] < ms -> window[0][k]) return; if (vty -> center[k] - vty -> radii[0] > ms -> window[1][k]) return; } /* plus one for convex; minus one for concave */ fsgn = ((fac -> shape == CONVEX) ? 1.0 : -1.0); /* set up circle for leaf */ for (k = 0; k < 3; k++) { cir_center[k] = vty -> center[k]; cir_axis[k] = ((k == 1) ? fsgn : 0.0); } cir = new_circle (cir_center, (double) 0.0, cir_axis); if (cir == NULL) { add_object (tail_cept, CIRCLE, "leaf circle"); add_function (tail_cept, "slice_sphere"); return; } lf = allocate_leaf (); if (lf == NULL) { add_object (tail_cept, LEAF, "leaf"); add_function (tail_cept, "slice_sphere"); return; } /* copy atom number from variety to leaf */ for (j = 0; j < MAXPA; j++) lf -> atmnum[j] = fac -> vty -> atmnum[j]; for (k = 0; k < 3; k++) lf -> focus[k] = vty -> center[k]; /* set up leaf fields */ lf -> cir = cir; lf -> shape = fac -> shape; lf -> type = fac -> vty -> type; lf -> fac = fac; lf -> side = OUTSIDE; lf -> comp = fac -> comp; lf -> input_hue = fac -> input_hue; /* y increment for lines of latitude on sphere */ yinc = fine_pixel; /* one leaf per line of latitude */ for (y = vty -> center[1] - vty -> radii[0] - yinc / 2; y < vty -> center[1] + vty -> radii[0]; y += yinc) { /* change circle center */ cir -> center[1] = y; /* radius of circle of latitude */ rad = (vty -> radii[0] * vty -> radii[0]) - (y - vty -> center[1]) * (y - vty -> center[1]); if (rad <= 0.0) continue; rad = sqrt (rad); if (rad <= 0.0) continue; cir -> radius = rad; /* leaf endpoints: west and east */ for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) lf -> ends[j][k] = cir -> center[k]; lf -> ends[0][0] -= rad; lf -> ends[1][0] += rad; /* determine accessibility of endpoints of leaf */ for (j = 0; j < 2; j++) { lf -> where[j] = point_in_face (lf -> ends[j], fac, 1); if (lf -> where[j] < 0) { ms -> n_bad_projection++; lf -> where[j] = 0; } } /* cut, clip and render (outer) leaf */ lf -> cep = 0; lf -> clip_ep = 0; cut_leaf (ms, current_surface, fine_pixel, lf); if (error()) return; if (current_surface -> clipping) { /* cut, clip and render (inner) leaf */ for (k = 0; k < 3; k++) cir -> axis[k] = ((k == 1) ? -fsgn : 0.0); lf -> cep = 0; lf -> clip_ep = 0; lf -> side = INSIDE; cut_leaf (ms, current_surface, fine_pixel, lf); if (error()) return; /* reset what we changed */ lf -> side = OUTSIDE; for (k = 0; k < 3; k++) cir -> axis[k] = ((k == 1) ? fsgn : 0.0); } } free_leaf (lf); free_circle (cir); return; }
void slice_cylinder (struct msscene *ms, struct surface *current_surface, double fine_pixel, struct face *fac) { int k, j; double axis_inc, a; double half_length, big_radius, cyl_radius; double cyl_axis[3], z_axis[3], base[3]; struct leaf *lf; struct circle *lfcir; struct variety *vty; struct cept *ex; vty = fac -> vty; cyl_radius = vty -> radii[0]; half_length = vty -> length / 2; big_radius = ((half_length > cyl_radius) ? half_length : cyl_radius); /* check versus window */ for (k = 0; k < 3; k++) { if (vty -> center[k] + big_radius < ms -> window[0][k]) return; if (vty -> center[k] - big_radius > ms -> window[1][k]) return; } /* leaf circle */ lfcir = allocate_circle (); if (lfcir == NULL) { ex = new_cept (MEMORY_ERROR, ALLOCATION, FATAL_SEVERITY); add_object (ex, CIRCLE, "leaf circle"); add_function (ex, "slice_cylinder"); add_source (ex, "msrender.c"); return; } /* leaf */ lf = allocate_leaf (); if (lf == NULL) { add_object (tail_cept, LEAF, "leaf"); add_function (tail_cept, "slice_sphere"); return; } /* set up circle for leaf */ lfcir -> radius = cyl_radius; for (k = 0; k < 3; k++) { lfcir -> center[k] = vty -> center[k]; lfcir -> axis[k] = vty -> axis[k]; cyl_axis[k] = vty -> axis[k]; lf -> focus[k] = vty -> center[k]; } /* check for end-on */ if (cyl_axis[0] == 0.0 && cyl_axis[1] == 0.0) { free_leaf (lf); free_circle (lfcir); return; } for (k = 0; k < 3; k++) z_axis[k] = ((k == 2) ? 1.0 : 0.0); cross (cyl_axis, z_axis, base); if (norm (base) <= 0.0) { free_leaf (lf); free_circle (lfcir); return; } normalize (base); /* copy 3 atom number from variety to leaf */ for (k = 0; k < MAXPA; k++) lf -> atmnum[k] = vty -> atmnum[k]; /* set up leaf fields */ lf -> cir = lfcir; lf -> shape = fac -> shape; lf -> type = fac -> vty -> type; lf -> fac = fac; lf -> side = OUTSIDE; lf -> comp = fac -> comp; lf -> input_hue = fac -> input_hue; /* increment for lines of latitude on cylinder */ axis_inc = fine_pixel; /* one leaf per line of latitude */ for (a = (-half_length-axis_inc/2); a < half_length; a += axis_inc) { /* change circle center */ for (k = 0; k < 3; k++) { lfcir -> center[k] = vty -> center[k] + a * cyl_axis[k]; lf -> focus[k] = lfcir -> center[k]; } /* leaf endpoints: west and east */ for (k = 0; k < 3; k++) { lf -> ends[0][k] = lfcir -> center[k] - cyl_radius * base[k]; lf -> ends[1][k] = lfcir -> center[k] + cyl_radius * base[k]; } /* determine accessibility of endpoints of leaf */ for (j = 0; j < 2; j++) lf -> where[j] = 1; /* cut, clip and render (outer) leaf */ lf -> cep = 0; lf -> clip_ep = 0; clip_leaf (ms, current_surface, fine_pixel, lf); if (error()) return; if (current_surface -> clipping) { /* cut, clip and render (inner) leaf */ for (k = 0; k < 3; k++) lfcir -> axis[k] = (-cyl_axis[k]); lf -> cep = 0; lf -> clip_ep = 0; lf -> side = INSIDE; clip_leaf (ms, current_surface, fine_pixel, lf); /* reset what we changed */ lf -> side = OUTSIDE; for (k = 0; k < 3; k++) lfcir -> axis[k] = cyl_axis[k]; } } free_leaf (lf); free_circle (lfcir); return; }
void slice_torus (struct msscene *ms, struct surface *current_surface, double fine_pixel, double probe_radius, struct face *fac) { int k, j, i, nfocus, near1, naif; double anginc, bigrad; double focus[3], vect1[3], vect2[3], vect[3], qvect[3]; double dtq, tcv[3]; double *foci = (double *) NULL; char message[MAXLINE]; struct leaf *lf; struct circle *cir1, *cir2, *cir3; struct circle *lfcir, *torcir; struct variety *vty, *atm1, *atm2; struct arc *a, *nxta; struct arc *torarc; struct vertex *torvtx[2]; struct vertex *qvtx; struct vertex *conevtx; struct cycle *cyc; struct edge *edg; struct cept *ex; vty = fac -> vty; if (vty -> type != TORUS) { ex = new_cept (GEOMETRY_ERROR, INCONSISTENCY, FATAL_SEVERITY); add_function (ex, "slice_torus"); add_source (ex, "msrender.c"); add_long (ex, "variety type", (long) vty -> type); return; } if (vty -> tube) { slice_elbow (ms, current_surface, fine_pixel, fac); return; } if (debug >= 2) { sprintf (message,"render saddle face for atoms %5d %5d", vty -> atmnum[0], vty -> atmnum[1]); inform(message); } /* get pointers to atom varieties */ atm1 = *(current_surface -> variety_handles + fac -> vty -> atmnum[0] - 1); atm2 = *(current_surface -> variety_handles + fac -> vty -> atmnum[1] - 1); /* check versus window */ bigrad = distance (atm1 -> center, atm2 -> center) + atm1 -> radii[0] + atm2 -> radii[0]; for (k = 0; k < 3; k++) { if (vty -> center[k] + bigrad < ms -> window[0][k]) return; if (vty -> center[k] - bigrad > ms -> window[1][k]) return; } /* leaf circle */ lfcir = allocate_circle (); if (error()) { add_object (tail_cept, CIRCLE, "leaf circle"); add_function (tail_cept, "slice_torus"); return; } /* leaf */ lf = allocate_leaf (); if (error()) { add_object (tail_cept, LEAF, "leaf"); add_function (tail_cept, "slice_sphere"); return; } /* torus circle radius, center, axis */ torcir = new_circle (vty -> center, vty -> radii[0], vty -> axis); if (torcir == NULL) { add_object (tail_cept, CIRCLE, "torus circle"); add_function (tail_cept, "slice_circle"); return; } /* torus arc */ torarc = allocate_arc (); if (error()) { add_object (tail_cept, ARC, "torus arc"); add_function (tail_cept, "slice_torus"); add_source (tail_cept, "msrender.c"); return; } for (j = 0; j < 2; j++) { torvtx[j] = allocate_vertex (); if (error()) { add_object (tail_cept, VERTEX, "torus vertex"); add_function (tail_cept, "slice_torus"); add_source (tail_cept, "msrender.c"); return; } } torarc -> cir = torcir; /* copy atom numbers from variety to leaf */ for (k = 0; k < MAXPA; k++) lf -> atmnum[k] = fac -> vty -> atmnum[k]; /* set up leaf fields */ lf -> cir = lfcir; lf -> shape = fac -> shape; lf -> type = fac -> vty -> type; lf -> fac = fac; lf -> cep = 0; lf -> clip_ep = 0; lf -> side = OUTSIDE; lf -> comp = fac -> comp; lf -> input_hue = fac -> input_hue; /* both endpoints of saddle face leaf are always accessible */ for (j = 0; j < 2; j++) lf -> where[j] = ACCESSIBLE; /* angular increment for rotation of leaf about torus axis */ anginc = fine_pixel / (vty -> radii[0]); /* next we need endpoints for torus arc */ /* get them from concave arcs bounding saddle face */ /* intialization */ cir1 = NULL; cir2 = NULL; cir3 = NULL; qvtx = NULL; conevtx = NULL; near1 = 0; /* look for concave arcs */ naif = 0; for (cyc = fac -> first_cycle; cyc != NULL; cyc = cyc -> next) for (edg = cyc -> first_edge; edg != NULL; edg = edg -> next) { naif++; a = edg -> arcptr; if (a -> shape == CONVEX) { cir3 = a -> cir; continue; } if (edg -> next == NULL) nxta = cyc -> first_edge -> arcptr; else nxta = edg -> next -> arcptr; if (along (edg, vty -> axis)) cir2 = a -> cir; else cir1 = a -> cir; /* check for cusp vertex */ if (a -> shape == CONCAVE && nxta -> shape == CONCAVE) { /* cusp point joints two concave arcs */ qvtx = a -> vtx[1-edg->orn]; } } dtq = probe_radius * probe_radius - vty -> radii[0] * vty -> radii[0]; /* later: note: check PI in bubbles */ if (naif == 1) { if (dtq <= 0.0) { ex = new_cept (GEOMETRY_ERROR, INCONSISTENCY, FATAL_SEVERITY); add_function (ex, "slice_torus"); add_source (ex, "msrender.c"); add_message(ex, "toroidal face with only one arc, but not cone"); return; } if (cir3 == NULL) { ex = new_cept (GEOMETRY_ERROR, INCONSISTENCY, FATAL_SEVERITY); add_function (ex, "slice_torus"); add_source (ex, "msrender.c"); add_message(ex, "toroidal face with only one arc, but no contact circle"); return; } /* cone */ qvtx = allocate_vertex (); if (error()) { add_object (tail_cept, VERTEX, "CUSP VERTEX"); add_function (tail_cept, "slice_torus"); add_source (tail_cept, "msrender.c"); return; } conevtx = qvtx; dtq = sqrt (dtq); for (k = 0; k < 3; k++) tcv[k] = cir3 -> center[k] - torcir -> center[k]; normalize (tcv); for (k = 0; k < 3; k++) qvtx -> center[k] = torcir -> center[k] + dtq * tcv[k]; /* hope this is enough */ } if (cir1 == NULL) informd2 ("cir1 null"); if (cir2 == NULL) informd2 ("cir2 null"); if (qvtx != NULL) informd2 ("cusp present"); /* check for cusp vertex */ if (qvtx != NULL) { for (k = 0; k < 3; k++) qvect[k] = qvtx -> center[k] - vty -> center[k]; near1 = (dot_product (qvect, vty -> axis) < 0.0); } /* check for hoop saddle face */ if (cir1 == NULL || cir2 == NULL) { for (j = 0; j < 2; j++) torarc -> vtx[j] = NULL; informd2 ("complete toroidal hoop"); } else { /* concave arc circle centers are endpoints of sphere rolling */ for (k = 0; k < 3; k++) { torvtx[0] -> center[k] = cir1 -> center[k]; torvtx[1] -> center[k] = cir2 -> center[k]; } for (j = 0; j < 2; j++) torarc -> vtx[j] = torvtx[j]; sprintf (message, "saddle rendering (from): %8.3f %8.3f %8.3f", cir1 -> center[0], cir1 -> center[1], cir1 -> center[2]); informd2 (message); sprintf (message, "saddle rendering (to) : %8.3f %8.3f %8.3f", cir2 -> center[0], cir2 -> center[1], cir2 -> center[2]); informd2 (message); } /* the probe sphere centers are the foci of the leaves */ nfocus = render_sub_arc (torarc, &foci, anginc); if (nfocus < 2) { ex = new_cept (LOGIC_ERROR, MSUNDERFLOW, FATAL_SEVERITY); add_function (ex, "slice_torus"); add_source (ex, "msrender.c"); add_long (ex, "number of foci", (long) nfocus); return; } sprintf (message, "nfocus = %d", nfocus); informd2 (message); /* create leaves */ for (i = 0; i < nfocus; i++) { for (k = 0; k < 3; k++) { focus[k] = (*(foci + 3 * i + k)); lfcir -> center[k] = focus[k]; lf -> focus[k] = focus[k]; } /* unit vectors from focus toward atoms */ for (k = 0; k < 3; k++) { vect1[k] = atm1 -> center[k] - focus[k]; vect2[k] = atm2 -> center[k] - focus[k]; } /* correct for cusp vertex */ if (qvtx != NULL) { if (near1) for (k = 0; k < 3; k++) vect2[k] = qvtx -> center[k] - focus[k]; else for (k = 0; k < 3; k++) vect1[k] = qvtx -> center[k] - focus[k]; } /* normalize vectors to unit length */ normalize (vect1); normalize (vect2); /* leaf circle radius is probe radius */ lfcir -> radius = probe_radius; /* set up endpoints of leaf */ for (k = 0; k < 3; k++) { lf -> ends[0][k] = focus[k] + lfcir -> radius * vect1[k]; lf -> ends[1][k] = focus[k] + lfcir -> radius * vect2[k]; } /* compute leaf circle axis */ for (k = 0; k < 3; k++) vect[k] = focus[k] - vty -> center[k]; cross (vty -> axis, vect, lfcir -> axis); normalize (lfcir -> axis); /* clip and render leaf */ clip_leaf (ms, current_surface, fine_pixel, lf); if (error()) return; } /* return temporary memory */ if (!free_doubles (foci, 0, VERTS)) { ex = new_cept (MEMORY_ERROR, FREEING, FATAL_SEVERITY); add_variable (ex, VERTS, "foci"); add_function (ex, "slice_torus"); add_source (ex, "msrender.c"); return; } free_leaf (lf); free_arc (torarc); free_circle (torcir); free_circle (lfcir); for (j = 0; j < 2; j++) free_vertex (torvtx[j]); if (conevtx != NULL) free_vertex (conevtx); return; }
void slice_elbow (struct msscene *ms, struct surface *current_surface, double fine_pixel, struct face *fac) { char message[MAXLINE]; struct leaf *lf; struct circle *lfcir, *torcir; struct arc *torarc; struct vertex *torvtx[2]; int i, j, k, nfocus, atmnum; double anginc, bigrad; double atmcen[3], ccens[2][3], cradii[2]; double focus[3], vect[3], z_axis[3], base[3]; struct variety *vty; double *foci; struct cept *ex; vty = fac -> vty; atmnum = vty -> atmnum[0]; if (debug >= 2) { sprintf (message,"render elbow face for atom %5d", atmnum); inform(message); } for (k = 0; k < 3; k++) atmcen[k] = *(current_surface -> atom_centers + 3 * (atmnum - 1) + k); for (j = 0; j < 2; j++) cradii[j] = vty -> radii[1]; for (j = 0; j < 2; j++) for (k = 0; k < 3; k++) { ccens[j][k] = vty -> ccens[j][k]; } bigrad = distance (atmcen, ccens[0]) + cradii[0]; for (k = 0; k < 3; k++) { if (atmcen[k] + bigrad < ms -> window[0][k]) return; if (atmcen[k] - bigrad > ms -> window[1][k]) return; } /* leaf circle */ lfcir = allocate_circle (); if (lfcir == NULL) { ex = new_cept (MEMORY_ERROR, ALLOCATION, FATAL_SEVERITY); add_object (ex, CIRCLE, "leaf circle"); add_function (ex, "slice_elbow"); add_source (ex, "msrender.c"); return; } /* leaf */ lf = allocate_leaf (); if (lf == NULL) { add_object (tail_cept, LEAF, "leaf"); add_function (tail_cept, "slice_sphere"); return; } /* torus circle radius, center, axis */ torcir = new_circle (vty -> center, vty -> radii[0], vty -> axis); if (torcir == NULL) { add_object (tail_cept, CIRCLE, "torus circle"); add_function (tail_cept, "slice_elbow"); return; } /* torus arc */ torarc = allocate_arc (); if (torarc == NULL) { add_object (tail_cept, ARC, "torus arc"); add_function (tail_cept, "slice_elbow"); add_source (tail_cept, "msrender.c"); return; } for (j = 0; j < 2; j++) { torvtx[j] = allocate_vertex (); if (error()) { add_object (tail_cept, VERTEX, "torus vertex"); add_function (tail_cept, "slice_elbow"); add_source (tail_cept, "msrender.c"); return; } } /* set up leaf fields */ for (k = 0; k < MAXPA; k++) lf -> atmnum[k] = vty -> atmnum[k]; lf -> cir = lfcir; lf -> shape = CONVEX; /* to avoid reversing normal vector */ lf -> type = vty -> type; lf -> fac = fac; lf -> cep = 0; lf -> clip_ep = 0; lf -> side = OUTSIDE; lf -> comp = fac -> comp; lf -> input_hue = fac -> input_hue; for (j = 0; j < 2; j++) lf -> where[j] = ACCESSIBLE; /* setup torus central circle for subdivision */ anginc = fine_pixel / ((vty -> radii[0] + cradii[0])); torcir -> radius = vty -> radii[0]; for (k = 0; k < 3; k++) { torcir -> center[k] = vty -> center[k]; torcir -> axis[k] = vty -> axis[k]; } torarc -> cir = torcir; for (j = 0; j < 2; j++) { torarc -> vtx[j] = torvtx[j]; for (k = 0; k < 3; k++) torvtx[j] -> center[k] = ccens[j][k]; } foci = (double *) NULL; nfocus = render_sub_arc (torarc, &foci, anginc); if (nfocus < 2) { ex = new_cept (LOGIC_ERROR, MSUNDERFLOW, FATAL_SEVERITY); add_function (ex, "slice_elbow"); add_source (ex, "msrender.c"); add_long (ex, "number of foci", (long) nfocus); return; } /* create leaves */ for (i = 0; i < nfocus; i++) { for (k = 0; k < 3; k++) { focus[k] = (*(foci + 3 * i + k)); lfcir -> center[k] = focus[k]; lf -> focus[k] = focus[k]; } lfcir -> radius = cradii[0]; /* compute tangent to torus central circle */ for (k = 0; k < 3; k++) vect[k] = focus[k] - vty -> center[k]; cross (vty -> axis, vect, lfcir -> axis); normalize (lfcir -> axis); for (k = 0; k < 3; k++) z_axis[k] = ((k == 2) ? 1.0 : 0.0); cross (lfcir -> axis, z_axis, base); if (norm (base) <= 0.0) { continue; } normalize (base); for (k = 0; k < 3; k++) { lf -> ends[0][k] = lfcir -> center[k] - lfcir -> radius * base[k]; lf -> ends[1][k] = lfcir -> center[k] + lfcir -> radius * base[k]; } /* clip and render leaf */ clip_leaf (ms, current_surface, fine_pixel, lf); if (error()) return; } free_doubles (foci, 0, VERTS); free_leaf (lf); free_arc (torarc); free_circle (torcir); free_circle (lfcir); for (j = 0; j < 2; j++) free_vertex (torvtx[j]); }
int main(){ //Standard start to triangle struct triangulateio in; struct triangulateio out; struct triangulateio *vorout = (struct triangulateio *) NULL; char Switches[] = "pq30a0.1z"; //Initialize the the arrays that will be used to pass data to triangle and to //take data from triangle init_triangleio( &in); init_triangleio( &out); //fill the circle for points fill_circle( &in, 50, 3.0); //Execute triangulate triangulate( Switches, &in, &out, vorout); //Initialize the variable for the the final summation tripoint triangle; double element; //Print he triangle, the nodes associated with that triangle and the moving sum // of the elements printf("Number of Triangles: %i\n", out.numberoftriangles); for(int i = 0; i < out.numberoftriangles; i++){ printf("Triangle %i: ",i); for(int j = 0; j < out.numberofcorners; j++){ printf("\t %d", out.trianglelist[i*out.numberofcorners + j]); if(j % 3 == 0){ triangle.a = out.trianglelist[i*out.numberofcorners + j]; } else if(j % 3 == 1){ triangle.b = out.trianglelist[i*out.numberofcorners + j]; } else { triangle.c = out.trianglelist[i*out.numberofcorners + j]; } } printf("\n"); printf("\t %d %d %d \n", triangle.a, triangle.b, triangle.c); element += passPoints(triangle, out.pointlist, 3.0); printf("Element: %f", element); printf("\n"); } printf("The integration over this mesh is %f \n", element); //Freeing the arrays free_circle( &in); free_circle( &out); // trifree( &out); return 0; }