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(); } } } }