void SurfacePlot::Isolines2FloorC() { if (isolines() <= 0 || actualData_p->empty()) return; double step = (actualData_p->hull().maxVertex.z - actualData_p->hull().minVertex.z) / isolines(); RGBA col; double zshift = actualData_p->hull().minVertex.z; TripleField nodes; TripleField intersection; double lambda = 0; GLStateBewarer sb2(GL_LINE_SMOOTH, false); for (int k = 0; k != isolines(); ++k) { double val = zshift + k * step; for (unsigned i=0; i!=actualDataC_->cells.size(); ++i) { nodes.clear(); unsigned cellnodes = actualDataC_->cells[i].size(); for (unsigned j=0; j!=cellnodes; ++j) { nodes.push_back(actualDataC_->nodes[actualDataC_->cells[i][j]]); } double diff = 0; for (unsigned m = 0; m!=cellnodes; ++m) { unsigned mm = (m+1)%cellnodes; if ((val>=nodes[m].z && val<=nodes[mm].z) || (val>=nodes[mm].z && val<=nodes[m].z)) { diff = nodes[mm].z - nodes[m].z; if (isPracticallyZero(diff)) // degenerated { intersection.push_back(nodes[m]); intersection.push_back(nodes[mm]); continue; } lambda = (val - nodes[m].z) / diff; intersection.push_back(Triple(nodes[m].x + lambda * (nodes[mm].x-nodes[m].x), nodes[m].y + lambda * (nodes[mm].y-nodes[m].y), val)); } } if (!intersection.empty()) { col = (*datacolor_p)(nodes[0].x,nodes[0].y,nodes[0].z); glColor4d(col.r, col.g, col.b, col.a); if (intersection.size()>2) { glBegin(GL_LINE_STRIP); for (unsigned dd = 0; dd!=intersection.size(); ++dd) { glVertex3d(intersection[dd].x, intersection[dd].y, zshift); } glEnd(); glBegin(GL_POINTS); glVertex3d(intersection[0].x,intersection[0].y,zshift); glEnd(); } else if (intersection.size() == 2) { glBegin(GL_LINES); glVertex3d(intersection[0].x,intersection[0].y,zshift); glVertex3d(intersection[1].x,intersection[1].y,zshift); // small pixel gap problem (see OpenGL spec.) glVertex3d(intersection[1].x,intersection[1].y,zshift); glVertex3d(intersection[0].x,intersection[0].y,zshift); glEnd(); } intersection.clear(); } } } }
void Curve::IsolinesC(unsigned comp, bool projected) { if (isolines() <= 0 || actualDataC_->empty()) return; Triple tmax = actualDataC_->hull().maxVertex; Triple tmin = actualDataC_->hull().minVertex; double delta = tmax(comp) - tmin(comp); double shift = tmin(comp); double step = delta / isolines(); RGBA col; TripleField nodes; TripleField intersection; double lambda = 0; GLStateBewarer sb2(GL_LINE_SMOOTH, false); for (unsigned int k = 0; k != isolines(); ++k) { double val = shift + k * step; for (unsigned int i = 0; i != actualDataC_->cells.size(); ++i) { nodes.clear(); unsigned int cellnodes = actualDataC_->cells[i].size(); for (unsigned int j = 0; j != cellnodes; ++j) { nodes.push_back(actualDataC_->nodes[actualDataC_->cells[i][j]]); } double diff = 0; for (unsigned int m = 0; m != cellnodes; ++m) { unsigned int mm = (m+1) % cellnodes; bool outer = (val >= nodes[mm](comp) && val <= nodes[m](comp)); bool inner = (val >= nodes[m](comp) && val <= nodes[mm](comp)); if (inner || outer) { diff = nodes[mm](comp) - nodes[m](comp); if (isPracticallyZero(diff)) { // degenerated intersection.push_back(nodes[m]); intersection.push_back(nodes[mm]); continue; } Triple intersect; double component[3]; lambda = (val - nodes[m](comp)) / diff; for (unsigned int c = 0; c!=3; ++c) { component[c] = (nodes[m](c) + lambda * (nodes[mm](c)-nodes[m](c))); } switch (comp) { case 0: intersect = Triple(val, component[1], component[2]); break; case 1: intersect = Triple(component[0], val, component[2]); break; case 2: intersect = Triple(component[0], component[1], val); break; } intersection.push_back(intersect); } } col = (*datacolor_p)(nodes[0].x,nodes[0].y,nodes[0].z); glColor4d(col.r, col.g, col.b, col.a); drawIntersections(intersection, shift, comp, projected); } } }