int VoxelMesh::gen_vertices(const dim3 &cube, unsigned int cubeflag, double level, std::vector<point> &pts, EdgeMesh &em) const { double v[8]; point newpts[4]; int cnt[4] = {0, 0, 0, 0}; for (int i = 0; i < 4; i++) newpts[i] = point(0, 0, 0); int cases = 0; // std::cout << "cube, (" << cube.i << ", " << cube.j << ", " << cube.k << ") -> " << cubeflag << ", case "; for (int i = 0; i < 8; i++) { dim3 cv = dim3::cube_vertex(i); double val = level; if (!( (cv.i == 0 && (cubeflag & (1 << 0))) || (cv.i == 1 && (cubeflag & (1 << 1))) || (cv.j == 0 && (cubeflag & (1 << 2))) || (cv.j == 1 && (cubeflag & (1 << 3))) || (cv.k == 0 && (cubeflag & (1 << 4))) || (cv.k == 1 && (cubeflag & (1 << 5))))) val = (*this)[cube + cv]; v[i] = val; if (val > level) cases |= (1 << i); } // std::cout << cases << std::endl; int code = edgeGroup[cases]; for (int i = 0; i < 12; i++) { edge e(i); int patchid = (code >> (2 * i)) & 3; double v1 = v[e.beg.vertex_id()]; double v2 = v[e.end.vertex_id()]; bool c1 = v1 > level; bool c2 = v2 > level; em.update_edge(cube, e, i, c1, c2, patchid); if (c1 == c2) { assert(patchid == 3); continue; } double w = (level - v1) / (v2 - v1); cnt[patchid]++; newpts[patchid] += edge_point(cube, e, w); } int patches = 0; for (int i = 0; i < 4; i++) if (cnt[i] > 0) { point p = newpts[i] * (1. / cnt[i]); // std::cout << "yield point " << p.x << ", " << p.y << ", " << p.z << std::endl; if (cubeflag & (1 << 0)) p.x = ll.x; if (cubeflag & (1 << 1)) p.x = ur.x; if (cubeflag & (1 << 2)) p.y = ll.y; if (cubeflag & (1 << 3)) p.y = ur.y; if (cubeflag & (1 << 4)) p.z = ll.z; if (cubeflag & (1 << 5)) p.z = ur.z; pts.push_back(p); patches++; } for (int i = patches; i < 4; i++) assert(cnt[i] == 0); return patches; }
int edge(int x0, int y0, int x1, int y1) { float m; float x; if (y0 == y1) return 0; x = x0; m = (float)(x0 - x1) / (float)(y0 - y1); if (y0 < y1) while (++y0 < y1) { x0 = (x += m) + .5; edge_point(x0, y0); } else while (--y0 > y1) { x0 = (x -= m) + .5; edge_point(x0, y0); } return 0; }
//************************************************************************************************* // Finds the point on the rect boundary that is closest to the arg_point. Closest is defined as // the minimum perpendicular distance. //************************************************************************************************* rspfDpt rspfDrect::findClosestEdgePointTo(const rspfDpt& arg_point) const { double dXleft = theUlCorner.x - arg_point.x; double dXright = theLrCorner.x - arg_point.x; double dYupper = theUlCorner.y - arg_point.y; double dYlower = theLrCorner.y - arg_point.y; rspfDpt edge_point (theLrCorner); if (dXleft*dXright < 0.0) edge_point.x = arg_point.x; else if (fabs(dXleft) < fabs(dXright)) edge_point.x = theUlCorner.x; if (dYupper*dYlower < 0.0) edge_point.y = arg_point.y; else if (fabs(dYupper) < fabs(dYlower)) edge_point.y = theUlCorner.y; return edge_point; }