template <class T>void _floodFill(T *m, XYPoint size, XYPoint xy, T rc, double tol) { XYStack s, offsets; XYPoint pt = xy; bool spanLeft,spanRight,offset=false; /* set the target color tc */ T tc = m[pt.x+pt.y*size.x]; /* FIXME: the offset workaround with another stack is ONLY used when * the reset color (rc) is the same as target color (tc). In this case * we reset to an offset color from rc first, keep coordinates of all * reset points and reset them to what we need at the end of the loop. * This does not affect the speed when the color is different as the * stack is not used then. */ T resetc = rc; if (fabs(tc-rc) <= tol) { offset=true; resetc = (T)(rc+tol+1); } // pushes the seed starting pixel s.push(pt); while(s.pop(pt)) { // climbs up along the column x as far as possible while(pt.y>=0 && fabs(m[pt.x+pt.y*size.x]-tc) <= tol) pt.y--; pt.y++; spanLeft=false; spanRight=false; /* to enable users to terminate this function */ R_CheckUserInterrupt(); // processes the column x while(pt.y<size.y && fabs(m[pt.x+pt.y*size.x]-tc) <= tol) { m[pt.x+pt.y*size.x]=resetc; if (offset) offsets.push(pt); if(!spanLeft && pt.x>0 && fabs(m[pt.x-1+pt.y*size.x]-tc) <= tol) { s.push(XYPoint(pt.x-1,pt.y)); spanLeft=true; } else if(spanLeft && pt.x>0 && fabs(m[pt.x-1+pt.y*size.x]-tc) > tol) spanLeft=false; if(!spanRight && pt.x<size.x-1 && fabs(m[pt.x+1+pt.y*size.x]-tc) <= tol) { s.push(XYPoint(pt.x+1,pt.y)); spanRight=true; } else if(spanRight && pt.x<size.x-1 && fabs(m[pt.x+1+pt.y*size.x]-tc) > tol) spanRight=false; pt.y++; } } while(offsets.pop(pt)) m[pt.x+pt.y*size.x]=rc; }
void DataMangler::AverageValues(XYGraph *graph) { double pvx = pow(0.1, m_di[0]->GetPrec()); int count; double slice; double dif = graph->m_dmax[0] - graph->m_dmin[0]; if (dif < pvx) { count = 1; slice = pvx; } else { count = 0; while (dif / count > pvx && count < 20) ++count; slice = dif / count; } std::deque<double> sums(count, 0); std::deque<int> counts(count, 0); std::deque< std::vector<DTime> > ptimes(count); for (size_t i = 0; i < graph->m_points_values.size(); ++i) { double& x = graph->m_points_values.at(i).first[0]; double& y = graph->m_points_values.at(i).first[1]; std::vector<DTime> × = graph->m_points_values.at(i).second; int idx = int((x - graph->m_dmin[0] - slice / 2) * count / dif); if (idx < 0) idx = 0; if (idx >= count) idx = count - 1; counts[idx]++; sums[idx] += y; for(unsigned int j = 0; j < times.size(); j++) ptimes[idx].push_back(times[j]); } graph->m_points_values.clear(); for (int i = 0; i < count; ++i) { int c = counts[i]; if (c == 0) continue; std::vector<double> xy(2); xy[0] = graph->m_dmin[0] + dif * i / count; xy[1] = sums[i] / c; graph->m_points_values.push_back(XYPoint(xy, ptimes[i])); } }
/* Templated version by Oleg Sklyar */ template <class T> void _fillAroundObjectHullT(T **m, T **canvas, const Box &box, int &rc) { XYStack s; XYPoint pt; bool spanLeft,spanRight; pt.x = box.l; pt.y = box.t; // pushes the starting pixel s.push(pt); while(s.pop(pt)) { // climbs up along the column x as far as possible while(pt.y>=box.t && (int)m[pt.x][pt.y]!=rc && (int)canvas[pt.x][pt.y]!=rc) pt.y--; pt.y++; spanLeft=false; spanRight=false; // processes the column x while(pt.y<=box.b && (int)m[pt.x][pt.y]!=rc) { R_CheckUserInterrupt(); canvas[pt.x][pt.y]=rc; if(!spanLeft && pt.x>box.l && (int)m[pt.x-1][pt.y]!=rc && (int)canvas[pt.x-1][pt.y]!=rc) { s.push(XYPoint(pt.x-1,pt.y)); spanLeft=true; } else if(spanLeft && pt.x>box.l && ((int)m[pt.x-1][pt.y]==rc || (int)canvas[pt.x-1][pt.y]==rc)) spanLeft=false; if(!spanRight && pt.x<box.r && (int)m[pt.x+1][pt.y]!=rc && (int)canvas[pt.x+1][pt.y]!=rc) { s.push(XYPoint(pt.x+1,pt.y)); spanRight=true; } else if(spanRight && pt.x<box.r && ((int)m[pt.x+1][pt.y]==rc || (int)canvas[pt.x+1][pt.y]==rc)) spanRight=false; pt.y++; } } }
void DataMangler::AssociateValues(XYGraph *graph) { int count = 0; std::map<std::vector<double>, std::vector<DTime> > points; for (size_t i = 0; i < m_draw_vals.size(); ++i) { std::vector<double> v; DTime time = m_draw_vals.at(i).second; for (size_t j = 0; j < graph->m_di.size(); j++) { ValueInfo &vi = m_draw_vals.at(i).first[j]; if (!vi.IsData()) goto next; v.push_back(vi.val); } points[v].push_back(time); if (count != 0) for (size_t j = 0; j < graph->m_di.size(); j++) { graph->m_min[j] = wxMin(graph->m_min[j], v[j]); graph->m_max[j] = wxMax(graph->m_max[j], v[j]); } else for (size_t j = 0; j < graph->m_di.size(); j++) graph->m_min[j] = graph->m_max[j] = v[j]; count++; next:; } std::map<std::vector<double>, std::vector<DTime> >::iterator i; std::vector<DTime>::iterator j; for (i = points.begin(); i != points.end(); i++) graph->m_points_values.push_back(XYPoint(i->first, i->second)); }
void Chart::processGrid(Grid *grid) { if (active) { /*MyVector3D *vorticities = 0; double *streams = 0;*/ if (grid == 0) { grid = lastGrid; /*if (grid != 0) { vorticities = grid->computeVorticity(); streams = grid->computeStream(Singleton::instance()->getPainterConfig()->getStreamIntegrationX(), Singleton::instance()->getPainterConfig()->getStreamIntegrationY()); }*/ } else { lastGrid = grid; /*vorticities = grid->computeVorticity(); streams = grid->computeStream(Singleton::instance()->getPainterConfig()->getStreamIntegrationX(), Singleton::instance()->getPainterConfig()->getStreamIntegrationY());*/ if (ui->chartType->currentText() == "-log(DeltaP)") { temp.push_back(XYPoint(grid->getSimulation()->getIterations(), -log10(grid->getSimulation()->getDeltaP()))); } if (ui->chartType->currentText() == "Drag") { grid->computeDrag(); if (grid->getDrags() > 0) { temp.push_back(XYPoint(grid->getSimulation()->getIterations(), grid->getDrag(0).norm())); } } if (ui->chartType->currentText() != "" && ui->time->isChecked()) { int x = ui->xValue->text().toInt() - 1, y = ui->yValue->text().toInt() - 1, z = ui->zValue->text().toInt() - 1; BaseCell *cell = grid->getGrid(y, x, z); if (cell != 0 && cell->isFluid()) { if (ui->chartType->currentText() == "Pressure") { temp.push_back(XYPoint(grid->getSimulation()->getIterations(), cell->getP(ui->other->text().toInt()))); } else if (ui->chartType->currentText() == "Velocity" && ui->axis->currentText() == "") { temp.push_back(XYPoint(grid->getSimulation()->getIterations(), cell->getU(ui->other->text().toInt()).norm())); } else if (ui->chartType->currentText() == "Velocity" && ui->axis->currentText() == "x") { temp.push_back(XYPoint(grid->getSimulation()->getIterations(), cell->getU(ui->other->text().toInt()).getX())); } else if (ui->chartType->currentText() == "Velocity" && ui->axis->currentText() == "y") { temp.push_back(XYPoint(grid->getSimulation()->getIterations(), cell->getU(ui->other->text().toInt()).getY())); } else if (ui->chartType->currentText() == "Velocity" && ui->axis->currentText() == "z") { temp.push_back(XYPoint(grid->getSimulation()->getIterations(), cell->getU(ui->other->text().toInt()).getZ())); /*} else if (ui->chartType->currentText() == "Vorticity" && ui->axis->currentText() == "") { temp.push_back(XYPoint(grid->getSimulation()->getIterations(), vorticities[x + y * grid->getConfig()->getWidth() + z * grid->getConfig()->getWidth() * grid->getConfig()->getHeight()].norm())); } else if (ui->chartType->currentText() == "Vorticity" && ui->axis->currentText() == "x") { temp.push_back(XYPoint(grid->getSimulation()->getIterations(), vorticities[x + y * grid->getConfig()->getWidth() + z * grid->getConfig()->getWidth() * grid->getConfig()->getHeight()].getX())); } else if (ui->chartType->currentText() == "Vorticity" && ui->axis->currentText() == "y") { temp.push_back(XYPoint(grid->getSimulation()->getIterations(), vorticities[x + y * grid->getConfig()->getWidth() + z * grid->getConfig()->getWidth() * grid->getConfig()->getHeight()].getY())); } else if (ui->chartType->currentText() == "Vorticity" && ui->axis->currentText() == "z") { temp.push_back(XYPoint(grid->getSimulation()->getIterations(), vorticities[x + y * grid->getConfig()->getWidth() + z * grid->getConfig()->getWidth() * grid->getConfig()->getHeight()].getZ())); } else if (ui->chartType->currentText() == "Stream") { temp.push_back(XYPoint(grid->getSimulation()->getIterations(), streams[x + y * grid->getConfig()->getWidth() + z * grid->getConfig()->getWidth() * grid->getConfig()->getHeight()]));*/ } } } } std::list<XYPoint> points; if (grid != 0) { for (int var = 0; var < (ui->x->isChecked() ? grid->getConfig()->getWidth() : (ui->y->isChecked() ? grid->getConfig()->getHeight() : ui->z->isChecked() ? grid->getConfig()->getLength() : 0)); var++) { int y = (ui->y->isChecked() ? var : ui->yValue->text().toInt() - 1); int x = (ui->x->isChecked() ? var : ui->xValue->text().toInt() - 1); int z = (ui->z->isChecked() ? var : ui->zValue->text().toInt() - 1); BaseCell *lattice = (grid->getGrid(y, x, z)); if (lattice != 0 && lattice->isFluid()) { /*MyVector3D vorticity = vorticities[x + y * grid->getConfig()->getWidth() + z * grid->getConfig()->getWidth() * grid->getConfig()->getHeight()]; double stream = streams[x + y * grid->getConfig()->getWidth() + z * grid->getConfig()->getWidth() * grid->getConfig()->getHeight()];*/ double value = 0; if (ui->chartType->currentText() == "Pressure") { value = lattice->getP(ui->other->text().toInt()); } else if (ui->chartType->currentText() == "Velocity" && ui->axis->currentText() == "") { value = lattice->getU(ui->other->text().toInt()).norm(); } else if (ui->chartType->currentText() == "Velocity" && ui->axis->currentText() == "x") { value = lattice->getU(ui->other->text().toInt()).getX(); } else if (ui->chartType->currentText() == "Velocity" && ui->axis->currentText() == "y") { value = lattice->getU(ui->other->text().toInt()).getY(); } else if (ui->chartType->currentText() == "Velocity" && ui->axis->currentText() == "z") { value = lattice->getU(ui->other->text().toInt()).getZ(); /*} else if (ui->chartType->currentText() == "Vorticity" && ui->axis->currentText() == "") { value = vorticity.norm(); } else if (ui->chartType->currentText() == "Vorticity" && ui->axis->currentText() == "x") { value = vorticity.getX(); } else if (ui->chartType->currentText() == "Vorticity" && ui->axis->currentText() == "y") { value = vorticity.getY(); } else if (ui->chartType->currentText() == "Vorticity" && ui->axis->currentText() == "z") { value = vorticity.getZ(); } else if (ui->chartType->currentText() == "Stream") { value = stream;*/ } points.push_back(XYPoint(var, value)); } } if (ui->chartType->currentText() == "-log(DeltaP)" || ui->chartType->currentText() == "Drag" || ui->time->isChecked()) { points = temp; } updateChart(points, curve); ui->chart->replot(); } //delete[] vorticities; } }
XYPoint ObstacleNode::Position() /*****************************************************************************/ { return(XYPoint(Data().xInMillimeters, Data().yInMillimeters)); }