void Curve::mapTriangleG(double *v1, double *v2, double *v3, const std::vector<double>& stops, int comp, double shift) { double z[] = {v1[2], v2[2], v3[2]}; std::sort(z, z + 3); double zmin = z[0], zmax = z[2]; std::vector<double> colorLevels = isocolors(stops, zmin, zmax); TripleField t; t.push_back(plot_p->transform(v1, comp)); t.push_back(plot_p->transform(v2, comp)); t.push_back(plot_p->transform(v3, comp)); if (colorLevels.empty()){ RGBA col = (*datacolor_p)(0, 0, 0.5*(zmin + zmax)); glColor4d(col.r, col.g, col.b, col.a); glBegin(GL_TRIANGLES); for (int i = 0; i < 3; i++) drawVertex(t[i], shift, comp); glEnd(); return; } std::vector<TripleField> cells = isocolorCells(t, colorLevels); if (cells.empty()) return; unsigned int polygons = cells.size(); for (unsigned int i = 0; i < polygons; i++){ TripleField cell = cells[i]; RGBA col = (*datacolor_p)(0, 0, 0.5*(cell[0].z + cell[2].z)); glColor4d(col.r, col.g, col.b, col.a); unsigned int points = cell.size(); if (points > 3) fillPolygonG(cell, comp, shift); else { glBegin(GL_TRIANGLES); for (unsigned int j = 0; j < points; j++) drawVertex(cell[j], shift, comp); glEnd(); } } }
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(); } } } }
std::vector<TripleField> isocolorCells(const TripleField& t, const std::vector<double>& colorLevels) { QList<Triple> intersections; unsigned int colorCount = colorLevels.size(), size = t.size(); for (unsigned int k = 0; k < colorCount; k++){ double val = colorLevels[k]; for (unsigned int i = 0; i < size; i++){ int ii = (i + 1)%size; Triple ti = t[i], tii = t[ii]; double zi = ti.z, zii = tii.z; if (val == zi){ if (!intersections.contains(ti)) intersections.push_back(ti); continue; } else if (val == zii){ if (!intersections.contains(tii)) intersections.push_back(tii); continue; } bool outer = (val > zii && val < zi); bool inner = (val > zi && val < zii); if (inner || outer){ Triple d = tii - ti; double f = (val - zi)/d(2); double component[3]; for (unsigned int j = 0; j < 3; j++) component[j] = ti(j) + f*d(j); intersections.push_back(Triple(component[0], component[1], val)); } } } std::vector<TripleField> cells; if (intersections.empty()) return cells; Triple p = intersections[0], pp = intersections[1]; TripleField firstCell, lastCell; firstCell.push_back(p); firstCell.push_back(pp); double level = p.z; for (unsigned int j = 0; j < size; j++){ Triple tj = t[j]; if (tj.z < level) firstCell.push_back(tj); } cells.push_back(firstCell); unsigned int intPairs = intersections.size()/2; for (unsigned int i = 1; i < intPairs; i++){ TripleField cell; cell.push_back(p); cell.push_back(pp); double prevLevel = p.z; unsigned int k = 2*i; p = intersections[k]; pp = intersections[k + 1]; level = p.z; for (unsigned int j = 0; j < size; j++){ Triple tj = t[j]; if (prevLevel < tj.z && tj.z < level) cell.push_back(tj); } cell.push_back(p); cell.push_back(pp); cells.push_back(cell); } lastCell.push_back(p); lastCell.push_back(pp); for (unsigned int j = 0; j < size; j++){ Triple tj = t[j]; if (tj.z > level) lastCell.push_back(tj); } cells.push_back(lastCell); return cells; }
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); } } }