void WriteCatmullRomCyclicPath(const Spline<int32>& spline, ByteBuffer& data) { data << spline.getPoint(1).y << spline.getPoint(1).x << spline.getPoint(1).z; // fake point, client will erase it from the spline after first cycle done for (int i = 1; i < spline.getPointCount() - 3; i++) data << spline.getPoint(i).y << spline.getPoint(i).x << spline.getPoint(i).z; //data.append<Vector3>(&spline.getPoint(1), count); }
void WriteLinearPath(const Spline<int32>& spline, ByteBuffer& data) { uint32 last_idx = spline.getPointCount() - 3; const Vector3* real_path = &spline.getPoint(1); data << last_idx; data << real_path[last_idx]; // destination if (last_idx > 1) { Vector3 middle = (real_path[0] + real_path[last_idx]) / 2.f; Vector3 offset; // first and last points already appended for (uint32 i = 1; i < last_idx; ++i) { offset = middle - real_path[i]; data.appendPackXYZ(offset.x, offset.y, offset.z); } } }
static Evaluation regularizedSqrt_(const Evaluation& x) { typedef Opm::Spline<Scalar> Spline; static const Scalar xMin = 1e-2; static const Scalar sqrtXMin = std::sqrt(xMin); static const Scalar fPrimeXMin = 1.0/(2*std::sqrt(xMin)); static const Scalar fPrime0 = 2*fPrimeXMin; static const Spline sqrtRegSpline(0, xMin, // x0, x1 0, sqrtXMin, // y0, y1 fPrime0, fPrimeXMin); // m0, m1 if (x > xMin) return Opm::sqrt(x); else if (x <= 0) return fPrime0 * x; else return sqrtRegSpline.eval(x); }
void PacketBuilder::WriteLinearPath(const MoveSpline& move_spline, ByteBuffer& data) { const Spline<int32> spline = move_spline._Spline(); uint32 last_idx = spline.getPointCount() - 3; const Vector3 * real_path = &spline.getPoint(1); data << last_idx; data << CalcTransportOffset(move_spline, real_path[last_idx]); // destination if (last_idx > 1) { Vector3 middle = (CalcTransportOffset(move_spline, real_path[0]) + CalcTransportOffset(move_spline, real_path[last_idx])) / 2.f; Vector3 offset; // first and last points already appended for (uint32 i = 1; i < last_idx; ++i) { offset = CalcTransportOffset(move_spline, middle) - CalcTransportOffset(move_spline, real_path[i]); data.appendPackXYZ(offset.x, offset.y, offset.z); } } }
void mouseListener(int button, int state, int x, int y){ if (state == GLUT_DOWN){ Vec3 point; switch(button){ case GLUT_LEFT_BUTTON : point = Vec3(x, g_nWinHeight-y, 0); cout << "ADDED POINT AT " << point << endl; spline.addPointAt(spline.pointCount(), point); break; case GLUT_RIGHT_BUTTON: int i = 0; for (i = 0; i < spline.segmentCount(); i++) { cout << "last" << spline.evaluate(i, 0.0) << endl; cout << "next" << spline.evaluate(i, 1.0) << endl; } break; } } glutPostRedisplay(); }
void testFull(const Spline &sp, const double *x, const double *y, double m0, double m1) { // test the common properties of splines testCommon(sp, x, y); static double eps = 1e-5; size_t n = sp.numSamples(); // make sure the derivative at both end points is correct double d0 = sp.evalDerivative(x[0]); double d1 = sp.evalDerivative(x[n-1]); if (std::abs(d0 - m0) > eps) OPM_THROW(std::runtime_error, "Invalid derivative at beginning of interval: is " << d0 << " ought to be " << m0); if (std::abs(d1 - m1) > eps) OPM_THROW(std::runtime_error, "Invalid derivative at end of interval: is " << d1 << " ought to be " << m1); }
void testNatural(const Spline &sp, const double *x, const double *y) { // test the common properties of splines testCommon(sp, x, y); static double eps = 1e-5; size_t n = sp.numSamples(); // make sure the second derivatives at both end points are 0 double d0 = sp.evalDerivative(x[0]); double d1 = sp.evalDerivative(x[0] + eps); double d2 = sp.evalDerivative(x[n-1] - eps); double d3 = sp.evalDerivative(x[n-1]); if (std::abs(d1 - d0)/eps > 1000*eps) OPM_THROW(std::runtime_error, "Invalid second derivative at beginning of interval: is " << (d1 - d0)/eps << " ought to be 0"); if (std::abs(d3 - d2)/eps > 1000*eps) OPM_THROW(std::runtime_error, "Invalid second derivative at end of interval: is " << (d3 - d2)/eps << " ought to be 0"); }
void display() { setCamera(); glClearColor(0.0f, 0.0f, 0.0f, 1.0f ); glClear(GL_COLOR_BUFFER_BIT); glDisable(GL_LIGHTING); glBegin(GL_LINES); glColor3f(0.5,0.5,0.5); for (int i = 0; i < spline.pointCount(); i++) { Vec3 p = spline.getPoint(i); glVertex4f(p.x,p.y,p.z,1.0); glVertex4f(0.0,-1.0,0.0,0.0); } for (int i = 0; i < (int) spline.segmentCount(); i++) { Vec3 last = spline.evaluate(i, 0.0); cout << i << "::" << last << endl; for(float t = 0.01; t < 1.0; t += 0.01){ Vec3 next = spline.evaluate(i, t); glVertex3f(last.x, last.y, last.z); glVertex3f(next.x, next.y, next.z); last = next; } cout << i << "l ::" << last << endl; } glFinish(); glutSwapBuffers(); // glutPostRedisplay(); }
// Eger esemenyeket lekezelo fuggveny void onMouse(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { // A GLUT_LEFT_BUTTON / GLUT_RIGHT_BUTTON illetve GLUT_DOWN / GLUT_UP float X = -((((screenWidth - (float) x) / screenWidth) * 2) - 1); float Y = ((((screenHeight - (float) y) / screenHeight) * 2) - 1); if (!spacepressed) { crs.addCP(X, Y); parabola.addCP(X, Y); } //cout << "x: " << X << " y: " << Y << "\n" << flush; glutPostRedisplay(); // Ilyenkor rajzold ujra a kepet } }
void WriteLinearPath(const Spline<int32>& spline, ByteBuffer& data) { uint32 last_idx = spline.getPointCount() - 3; const Vector3 * real_path = &spline.getPoint(1); data << last_idx; data << real_path[last_idx]; // destination if (last_idx > 1) { Vector3 middle = (real_path[0] + real_path[last_idx]) / 2.f; Vector3 offset; // first and last points already appended for (uint32 i = 1; i < last_idx; ++i) { offset = middle - real_path[i]; data.appendPackXYZ(offset.x, offset.y, offset.z); } } // Unknow 5.0.5 MoP uint16 unkCount = 0; data << uint16(unkCount); // unk 5.0.5 count if (unkCount) { data << float(0); data << uint16(0); data << uint16(0); data << float(0); data << uint16(0); for(int i = 0; i < unkCount; i++) { data << uint16(0); data << uint16(0); } } }
void FiretrailApp::update() { const auto ray = mCamera.generateRay(getMousePos() - getWindowPos(), getWindowSize()); float result = .0f; ray.calcPlaneIntersection(vec3(.0f, .0f, 5.0f), vec3(.0f, -2.0f, 1.0f), &result); mHeadPosition += (ray.calcPosition(result) - mHeadPosition) * .8f; mSpline.pushPoint(mHeadPosition); const auto length = mSpline.getLength(); if (length <= .0f) return; auto mappedPosAttrib = mVboMesh->mapAttrib3f( geom::POSITION ); const auto d = min(mMaxDSlice, length / (float)NUM_SPLINE_NODES); for (size_t i = 0; i < NUM_SPLINE_NODES; ++i) { *mappedPosAttrib++ = mSpline.positionAtLength(d * i); } mappedPosAttrib.unmap(); mFps = getAverageFps(); if (mRecordingMovie) { if( mMovieExporter && getElapsedFrames() > 1 && getElapsedFrames() < MAX_MOVIE_FRAMES ) { mMovieExporter->addFrame( copyWindowSurface() ); } else if( mMovieExporter && getElapsedFrames() >= MAX_MOVIE_FRAMES ) { endMovieRecording(); } } }
void testMonotonic(const Spline &sp, const double *x, const double *y) { // test the common properties of splines testCommon(sp, x, y); size_t n = sp.numSamples(); for (size_t i = 0; i < n - 1; ++ i) { // make sure that the spline is monotonic for each interval // between sampling points if (!sp.monotonic(x[i], x[i + 1])) OPM_THROW(std::runtime_error, "Spline says it is not monotonic in interval " << i << " where it should be"); // test the intersection methods double d = (y[i] + y[i+1])/2; double interX = sp.template intersectInterval<double>(x[i], x[i+1], /*a=*/0, /*b=*/0, /*c=*/0, d); double interY = sp.eval(interX); if (std::abs(interY - d) > 1e-5) OPM_THROW(std::runtime_error, "Spline::intersectInterval() seems to be broken: " << sp.eval(interX) << " - " << d << " = " << sp.eval(interX) - d << "!"); } // make sure the spline says to be monotonic on the (extrapolated) // left and right sides if (!sp.monotonic(x[0] - 1.0, (x[0] + x[1])/2, /*extrapolate=*/true)) OPM_THROW(std::runtime_error, "Spline says it is not monotonic on left side where it should be"); if (!sp.monotonic((x[n - 2]+ x[n - 1])/2, x[n-1] + 1.0, /*extrapolate=*/true)) OPM_THROW(std::runtime_error, "Spline says it is not monotonic on right side where it should be"); for (size_t i = 0; i < n - 2; ++ i) { // make sure that the spline says that it is non-monotonic for // if extrema are within the queried interval if (sp.monotonic((x[i] + x[i + 1])/2, (x[i + 1] + x[i + 2])/2)) OPM_THROW(std::runtime_error, "Spline says it is monotonic in interval " << i << " where it should not be"); } }
void WriteCatmullRomPath(const Spline<int32>& spline, ByteBuffer& data) { uint32 count = spline.getPointCount() - 3; data << count; data.append<Vector3>(&spline.getPoint(2), count); // Unknow 5.0.5 MoP uint16 unkCount = 0; data << uint16(unkCount); // unk 5.0.5 count if (unkCount) { data << float(0); data << uint16(0); data << uint16(0); data << float(0); data << uint16(0); for(int i = 0; i < unkCount; i++) { data << uint16(0); data << uint16(0); } } }
// Rajzolas, ha az alkalmazas ablak ervenytelenne valik, akkor ez a fuggveny hivodik meg void onDisplay() { glClearColor(0.0f, 1.0f, 1.0f, 1.0f); // torlesi szin beallitasa //glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // torlesi szin beallitasa glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // kepernyo torles // Peldakent atmasoljuk a kepet a rasztertarba //glDrawPixels(screenWidth, screenHeight, GL_RGB, GL_FLOAT, image); parabola.draw(); crs.draw(); /* glPointSize(6); glColor3f(0, 0, 0); glBegin(GL_POINTS); glVertex2f(-0.9f, 0.0f); glVertex2f(0.9f, 0.0f); glVertex2f(0.0f, 0.9f); glVertex2f(0.0f, -0.9f); glEnd(); */ glColor3f(1, 1, 1); glBegin(GL_LINES); glVertex2f(-1.0f, 0.0f); glVertex2f(1.0f, 0.0f); glEnd(); glBegin(GL_LINES); glVertex2f(0.0f, 1.0f); glVertex2f(0.0f, -1.0f); glEnd(); /* glPointSize(4); glBegin(GL_POINTS); for (float i = -1.0f; i < 1.1f; i += 0.1f) { for (float j = -1.0f; j < 1.1f; j += 0.1f) { glVertex2f(i, j); } } glEnd();*/ glutSwapBuffers(); // Buffercsere: rajzolas vege }
void WriteLinearPath(const Spline<int32>& spline, ByteBuffer& data) { Movement::SplineBase::ControlArray const& pathPoint = spline.getPoints(); // get ref of whole path points array uint32 pathSize = spline.last() - spline.first() - 1; // -1 as we send destination first and last index is destination MANGOS_ASSERT(pathSize >= 0); // should never be less than 0 Vector3 destination = pathPoint[spline.last()]; // destination of this path should be send right after path size data << pathSize; data << destination; for (uint32 i = spline.first(); i < spline.first() + pathSize; i++) // from first real index (this array contain also special data) { Vector3 offset = destination - pathPoint[i]; // we have to send offset relative to destination instead of directly path point. data.appendPackXYZ(offset.x, offset.y, offset.z); // we have to pack x,y,z before send } }
void WriteCatmullRomPath(const Spline<int32>& spline, ByteBuffer& data) { uint32 count = spline.getPointCount() - 3; data << count; data.append<Vector3>(&spline.getPoint(2), count); }
void Data3DTreeDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const { const Data3DTreeModel* pData3DTreeModel = static_cast<const Data3DTreeModel*>(index.model()); const AbstractTreeItem* pAbstractItem = static_cast<const AbstractTreeItem*>(pData3DTreeModel->itemFromIndex(index)); switch(pAbstractItem->type()) { case MetaTreeItemTypes::SurfaceColorGyri: { QColor color = index.model()->data(index, MetaTreeItemRoles::SurfaceColorGyri).value<QColor>(); QColorDialog* pColorDialog = static_cast<QColorDialog*>(editor); pColorDialog->setCurrentColor(color); break; } case MetaTreeItemTypes::SurfaceColorSulci: { QColor color = index.model()->data(index, MetaTreeItemRoles::SurfaceColorSulci).value<QColor>(); QColorDialog* pColorDialog = static_cast<QColorDialog*>(editor); pColorDialog->setCurrentColor(color); break; } case MetaTreeItemTypes::RTDataColormapType: { QString colormap = index.model()->data(index, MetaTreeItemRoles::RTDataColormapType).toString(); QComboBox* pComboBox = static_cast<QComboBox*>(editor); pComboBox->setCurrentText(colormap); break; } case MetaTreeItemTypes::RTDataNormalizationValue: { Spline* pSpline = static_cast<Spline*>(editor); int width = pSpline->size().width(); int height = pSpline->size().height(); if (pSpline->size().width() < 200 && pSpline->size().height() < 200) { pSpline->resize(600,400); //resize histogram to be readable with default size } else { width = pSpline->size().width(); //keeps the size of the histogram height = pSpline->size().height(); pSpline->resize(width,height); } return; } case MetaTreeItemTypes::RTDataTimeInterval: { int value = index.model()->data(index, MetaTreeItemRoles::RTDataTimeInterval).toInt(); QSpinBox* pSpinBox = static_cast<QSpinBox*>(editor); pSpinBox->setValue(value); break; } case MetaTreeItemTypes::RTDataVisualizationType: { QString visType = index.model()->data(index, MetaTreeItemRoles::RTDataVisualizationType).toString(); QComboBox* pComboBox = static_cast<QComboBox*>(editor); pComboBox->setCurrentText(visType); break; } case MetaTreeItemTypes::SurfaceColor: { QColor color = index.model()->data(index, MetaTreeItemRoles::SurfaceColor).value<QColor>(); QColorDialog* pColorDialog = static_cast<QColorDialog*>(editor); pColorDialog->setCurrentColor(color); break; } case MetaTreeItemTypes::PointColor: { QColor color = index.model()->data(index, MetaTreeItemRoles::PointColor).value<QColor>(); QColorDialog* pColorDialog = static_cast<QColorDialog*>(editor); pColorDialog->setCurrentColor(color); break; } case MetaTreeItemTypes::RTDataNumberAverages: { int value = index.model()->data(index, MetaTreeItemRoles::RTDataNumberAverages).toInt(); QSpinBox* pSpinBox = static_cast<QSpinBox*>(editor); pSpinBox->setValue(value); break; } case MetaTreeItemTypes::SurfaceAlpha: { int value = index.model()->data(index, MetaTreeItemRoles::SurfaceAlpha).toDouble(); QSpinBox* pSpinBox = static_cast<QSpinBox*>(editor); pSpinBox->setValue(value); break; } case MetaTreeItemTypes::SurfaceTranslateX: { double value = index.model()->data(index, MetaTreeItemRoles::SurfaceTranslateX).toDouble(); QDoubleSpinBox* pDoubleSpinBox = static_cast<QDoubleSpinBox*>(editor); pDoubleSpinBox->setValue(value); break; } case MetaTreeItemTypes::SurfaceTranslateY: { double value = index.model()->data(index, MetaTreeItemRoles::SurfaceTranslateY).toDouble(); QDoubleSpinBox* pDoubleSpinBox = static_cast<QDoubleSpinBox*>(editor); pDoubleSpinBox->setValue(value); break; } case MetaTreeItemTypes::SurfaceTranslateZ: { double value = index.model()->data(index, MetaTreeItemRoles::SurfaceTranslateZ).toDouble(); QDoubleSpinBox* pDoubleSpinBox = static_cast<QDoubleSpinBox*>(editor); pDoubleSpinBox->setValue(value); break; } case MetaTreeItemTypes::NetworkThreshold: { Spline* pSpline = static_cast<Spline*>(editor); int width = pSpline->size().width(); int height = pSpline->size().height(); if (pSpline->size().width() < 200 && pSpline->size().height() < 200) //pSpline initializes with size (137,15) { pSpline->resize(800,600); //resize histogram to be readable with default size } else { width = pSpline->size().width(); //keeps the size of the histogram height = pSpline->size().height(); pSpline->resize(width,height); } return; } default: // do nothing; break; } QItemDelegate::setEditorData(editor, index); }
int main(int argc, char *argv[]) { using namespace magnet::math; Spline spline; //Add points to the spline in any order, they're sorted in ascending //x later. (If you want to spline a circle you'll need to change the //class) spline.addPoint(0, 0.0); spline.addPoint(40.0/255, 0.0); spline.addPoint(60.0/255, 0.2); spline.addPoint(63.0/255, 0.05); spline.addPoint(80.0/255, 0.0); spline.addPoint(82.0/255, 0.9); spline.addPoint(1.0, 1.0); //spline.addPoint(0, 0); //spline.addPoint(0.75, 0.5); //spline.addPoint(1, 1); //spline.addPoint(0.2, 0.6); //spline.addPoint(0.5, 0.6); { //We can extract the original data points by treating the spline as //a read-only STL container. std::ofstream of("orig.dat"); for (Spline::const_iterator iPtr = spline.begin(); iPtr != spline.end(); ++iPtr) of << iPtr->first << " " << iPtr->second << "\n"; } { //A "natural spline" where the second derivatives are set to 0 at the boundaries. //Each boundary condition is set seperately //The following aren't needed as its the default setting. The //zero values are the second derivatives at the spline points. spline.setLowBC(Spline::FIXED_2ND_DERIV_BC, 0); spline.setHighBC(Spline::FIXED_2ND_DERIV_BC, 0); //Note: We can calculate values outside the range spanned by the //points. The extrapolation is based on the boundary conditions //used. std::ofstream of("spline.natural.dat"); for (double x(-0.2); x <= 1.2001; x += 0.005) of << x << " " << spline(x) << "\n"; } { //A spline with a fixed first derivative at the boundaries //The zero values are the value of the gradient at that point spline.setLowBC(Spline::FIXED_1ST_DERIV_BC, 0); spline.setHighBC(Spline::FIXED_1ST_DERIV_BC, 0); std::ofstream of("spline.fixedy1.dat"); for (double x(-0.2); x <= 1.2001; x += 0.005) of << x << " " << spline(x) << "\n"; } { //A spline which turns into a parabola at the boundaries. //This BC does not need extra parameters, so just the condition is //enough. spline.setLowBC(Spline::PARABOLIC_RUNOUT_BC); spline.setHighBC(Spline::PARABOLIC_RUNOUT_BC); std::ofstream of("spline.parabolicrunout.dat"); for (double x(-0.2); x <= 1.2001; x += 0.005) of << x << " " << spline(x) << "\n"; } { //A spline which turns into a parabola at the boundaries. //This BC does not need extra parameters, so just the condition is //enough. spline.setLowBC(Spline::FIXED_1ST_DERIV_BC, 100); spline.setHighBC(Spline::PARABOLIC_RUNOUT_BC); std::ofstream of("spline.mixed.dat"); for (double x(-0.2); x <= 1.2001; x += 0.005) of << x << " " << spline(x) << "\n"; } // The following class uses splines to interpolate between color // values to make a "transfer function". // { // magnet::color::TransferFunction tf; // tf.addKnot(0, 0.91, 0.7, 0.61, 0.0); // tf.addKnot(40.0/255, 0.91, 0.7, 0.61, 0.0); // tf.addKnot(60.0/255, 0.91, 0.7, 0.61, 0.2); // tf.addKnot(63.0/255, 0.91, 0.7, 0.61, 0.05); // tf.addKnot(80.0/255, 0.91, 0.7, 0.61, 0.0); // tf.addKnot(82.0/255, 1.0, 1.0, 0.85, 0.9); // tf.addKnot(1.0, 1.0, 1.0, 0.85, 1.0); // // //tf.getColorMap(); // } }
int main(int argc, char **argv) { using Calibration::HistogramF; using Calibration::VarProcessor; ROOT::Cintex::Cintex::Enable(); if (argc != 3) { std::cerr << "Syntax: " << argv[0] << " <MVA File> " << "<output ROOT file>" << std::endl; return 1; } Calibration::MVAComputer *calib = MVAComputer::readCalibration(argv[1]); if (!calib) return 1; std::map<std::string, HistogramF*> histos; std::vector<VarProcessor*> procs = calib->getProcessors(); for(unsigned int z = 0; z < procs.size(); ++z) { VarProcessor *proc = procs[z]; if (!proc) continue; std::ostringstream ss3; ss3 << (z + 1); Calibration::ProcLikelihood *lkh = dynamic_cast<Calibration::ProcLikelihood*>(proc); Calibration::ProcNormalize *norm = dynamic_cast<Calibration::ProcNormalize*>(proc); if (lkh) { for(unsigned int i = 0; i < lkh->pdfs.size(); i++) { std::ostringstream ss2; ss2 << (i + 1); histos["proc" + ss3.str() + "_sig" + ss2.str()] = &lkh->pdfs[i].signal; histos["proc" + ss3.str() + "_bkg" + ss2.str()] = &lkh->pdfs[i].background; } } else if (norm) { for(unsigned int i = 0; i < norm->distr.size(); i++) { std::ostringstream ss2; ss2 << (i + 1); histos["proc" + ss3.str() + "_norm" + ss2.str()] = &norm->distr[i]; } } } TFile *f = TFile::Open(argv[2], "RECREATE"); if (!f) return 2; for(std::map<std::string, HistogramF*>::const_iterator iter = histos.begin(); iter != histos.end(); ++iter) { std::string name = iter->first; HistogramF *histo = iter->second; unsigned int size = histo->values().size() - 2; std::vector<double> values( histo->values().begin() + 1, histo->values().end() - 1); Spline spline; spline.set(values.size(), &values.front()); double min = histo->range().min; double max = histo->range().max; TH1F *h = new TH1F((name + "_histo").c_str(), (name + "_histo").c_str(), size, min - 0.5 * (max - min) / size, max + 0.5 * (max - min) / size); TH1F *s = new TH1F((name + "_spline").c_str(), (name + "_spline").c_str(), size * precision, min, max); for(unsigned int i = 0; i < size; i++) { h->SetBinContent(i + 1, histo->values()[i + 1]); for(int j = 0; j < precision; j++) { unsigned int k = i * precision + j; double x = (k + 0.5) / (size * precision); double v = spline.eval(x); s->SetBinContent(k, v); } } } f->Write(); delete f; return 0; }
void WriteUncompressedPath(Spline<int32> const& spline, ByteBuffer& data) { uint32 count = spline.getPointCount() - 3; data << count; data.append<Vector3>(&spline.getPoint(2), count); }
void WriteUncompressedPath(Spline<int32> const& spline, ByteBuffer& data) { for (int i = 1; i < spline.getPointCount() - 1; i++) data << spline.getPoint(i).y << spline.getPoint(i).x << spline.getPoint(i).z; }
void WriteUncompressedCyclicPath(Spline<int32> const& spline, ByteBuffer& data) { uint32 count = spline.getPointCount() - 3; data << spline.getPoint(1); // fake point, client will erase it from the spline after first cycle done data.append<Vector3>(&spline.getPoint(1), count); }
void PathPlanner::turnToGo(const RobotPosition & robotPos, SerialCommunication & reportData) { //take next point (X,Y) positions given by MatLab, calculate phi to turn towards, then go straight if (currentTask == Task::IDLE) { // waiting to receive command x,y desiredMVR = 0; desiredMVL = 0; if (!reportData.finished){ currentTask = Task::TURN; turnBegin = robotPos.Phi; if(reportData.commandIsTurn) { turnEnd = reportData.commandPhi; } else { Vector dist = reportData.commandPos - robotPos.pos; // skip small movements if(dist.magnitudeSq() < 0.025*0.025) currentTask = Task::DONE; turnEnd = (reportData.commandIsReversed ? -dist : dist).angle(); } } } if (currentTask == Task::TURN) { //turn towards next point static const Spline turnSpline(0, 1, 0.3, 0.1); // interpolate our motor speeds quadratically in angle float through_turn = unlerp(turnBegin, turnEnd, robotPos.Phi); float speed = sgn(turnEnd - turnBegin) * turnSpline.eval_dp(through_turn); desiredMVR = speed; desiredMVL = -speed; // move on if(through_turn >= 1 || turnBegin == turnEnd) { desiredMVR = 0; desiredMVL = 0; currentTask = Task::STRAIGHT; pathGoal = robotPos.pathDistance + (reportData.commandPos - robotPos.pos).magnitude(); // if we're just turning, this is our last step if(reportData.commandIsTurn) currentTask = Task::DONE; } } if (currentTask == Task::STRAIGHT) { //now go straight to next point float speed = 0.4; // slow down near the goal const float slow_within = 0.2; const float slow_to = 0.15; float to_go = pathGoal - robotPos.pathDistance; if (to_go < slow_within) speed = lerp(slow_to, speed, to_go / slow_within); if (to_go > 0) { //if we aren't there yet, keep going desiredMVR = speed; desiredMVL = speed; if(reportData.commandIsReversed) { desiredMVR = -desiredMVR; desiredMVL = -desiredMVL; } bool done = OrientationController(robotPos, reportData); if(done) currentTask = Task::DONE; } else { currentTask = Task::DONE; } } if (currentTask == Task::DONE) { //done desiredMVR = 0; desiredMVL = 0; currentTask = Task::IDLE; Serial.println("NEXT POINT"); reportData.updateStatus(true); } }
void ExportFileFunctions::loadYRadiusValuesForCurveInterpolatedSmooth (const DocumentModelCoords &modelCoords, const MainWindowModel &modelMainWindow, const Points &points, const ExportValuesXOrY &xThetaValues, const Transformation &transformation, QVector<QString*> &yRadiusValues) const { LOG4CPP_INFO_S ((*mainCat)) << "ExportFileFunctions::loadYRadiusValuesForCurveInterpolatedSmooth"; // Convert screen coordinates to graph coordinates, in vectors suitable for spline fitting vector<double> t; vector<SplinePair> xy; ExportOrdinalsSmooth ordinalsSmooth; ordinalsSmooth.loadSplinePairsWithTransformation (points, transformation, t, xy); // Formatting FormatCoordsUnits format; QString dummyXThetaOut; if (points.count() == 0) { // Since there are no values, leave the field empty for (int row = 0; row < xThetaValues.count(); row++) { *(yRadiusValues [row]) = ""; } } else if (points.count() == 1 || points.count() == 2) { // Apply the single value everywhere (N=1) or do linear interpolation (N=2) for (int row = 0; row < xThetaValues.count(); row++) { double xTheta = xThetaValues.at (row); double yRadius; if (points.count() == 1) { yRadius = xy.at (0).y (); } else { double x0 = xy.at (0).x (); double x1 = xy.at (1).x (); double y0 = xy.at (0).y (); double y1 = xy.at (1).y (); if (x0 == x1) { // Cannot do linear interpolation using two points at the same x value yRadius = xy.at (0).y (); } else { double s = (xTheta - x0) / (x1 - x0); yRadius = (1.0 - s) * y0 + s * y1; } } format.unformattedToFormatted (xTheta, yRadius, modelCoords, modelMainWindow, dummyXThetaOut, *(yRadiusValues [row]), transformation); } } else { // Iteration accuracy versus number of iterations 8->256, 10->1024, 12->4096. Single pixel accuracy out of // typical image size of 1024x1024 means around 10 iterations gives decent accuracy for numbers much bigger // than 1. A value of 12 gave some differences in the least significant figures of numbers like 10^-3 in // the regression tests. Toggling between 30 and 32 made no difference in the regression tests. const int MAX_ITERATIONS = 32; // Spline class requires at least one point if (xy.size() > 0) { // Fit a spline Spline spline (t, xy); // Get value at desired points for (int row = 0; row < xThetaValues.count(); row++) { double xTheta = xThetaValues.at (row); SplinePair splinePairFound = spline.findSplinePairForFunctionX (xTheta, MAX_ITERATIONS); double yRadius = splinePairFound.y (); // Save y/radius value for this row into yRadiusValues, after appropriate formatting QString dummyXThetaOut; format.unformattedToFormatted (xTheta, yRadius, modelCoords, modelMainWindow, dummyXThetaOut, *(yRadiusValues [row]), transformation); } } } }
ExportValuesOrdinal ExportOrdinalsSmooth::ordinalsAtIntervalsGraph (const vector<double> &t, const vector<SplinePair> &xy, double pointsInterval) const { LOG4CPP_INFO_S ((*mainCat)) << "ExportOrdinalsSmooth::ordinalsAtIntervalsGraph"; const double NUM_SMALLER_INTERVALS = 1000; // Results. Initially empty, but at the end it will have tMin, ..., tMax ExportValuesOrdinal ordinals; // Fit a spline Spline spline (t, xy); // Integrate the distances for the subintervals double integratedSeparation = 0; QPointF posLast (xy [0].x(), xy [0].y()); // Simplest method to find the intervals is to break up the curve into many smaller intervals, and then aggregate them // into intervals that, as much as possible, have the desired length. Simplicity wins out over accuracy in this // approach - accuracy is sacrificed to achieve simplicity double tMin = t.front(); double tMax = t.back(); double tLast = 0.0; int iTLastInterval = 0; for (int iT = 0; iT < NUM_SMALLER_INTERVALS; iT++) { double t = tMin + ((tMax - tMin) * iT) / (NUM_SMALLER_INTERVALS - 1.0); SplinePair pairNew = spline.interpolateCoeff(t); QPointF posNew = QPointF (pairNew.x(), pairNew.y()); QPointF posDelta = posNew - posLast; double integratedSeparationDelta = qSqrt (posDelta.x() * posDelta.x() + posDelta.y() * posDelta.y()); integratedSeparation += integratedSeparationDelta; while (integratedSeparation >= pointsInterval) { // End of current interval, and start of next interval. For better accuracy without having to crank up // the number of points by orders of magnitude, we use linear interpolation double sInterp; if (iT == 0) { sInterp = 0.0; } else { sInterp = (double) pointsInterval / (double) integratedSeparation; } double tInterp = (1.0 - sInterp) * tLast + sInterp * t; integratedSeparation -= pointsInterval; // Part of delta that was not used gets applied to next interval tLast = tInterp; ordinals.push_back (tInterp); iTLastInterval = iT; } tLast = t; posLast = posNew; } if (iTLastInterval < NUM_SMALLER_INTERVALS - 1) { // Add last point so we end up at tMax ordinals.push_back (tMax); } return ordinals; }
inline int32 operator()(Spline<int32>& s, int32 i) { return Movement::computeFallTime(start_elevation - s.getPoint(i+1).z, false) * 1000.f; }
inline int32 operator()(Spline<int32>& s, int32 i) { time += (s.SegLength(i) * velocityInv); return time; }
QWidget *Data3DTreeDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option , const QModelIndex& index) const { const Data3DTreeModel* pData3DTreeModel = static_cast<const Data3DTreeModel*>(index.model()); const AbstractTreeItem* pAbstractItem = static_cast<const AbstractTreeItem*>(pData3DTreeModel->itemFromIndex(index)); switch(pAbstractItem->type()) { case MetaTreeItemTypes::SurfaceColorGyri: { QColorDialog *pColorDialog = new QColorDialog(parent); connect(pColorDialog, &QColorDialog::currentColorChanged, this, &Data3DTreeDelegate::onEditorEdited); pColorDialog->setWindowTitle("Select Gyri Color"); pColorDialog->show(); return pColorDialog; } case MetaTreeItemTypes::SurfaceColorSulci: { QColorDialog *pColorDialog = new QColorDialog(); connect(pColorDialog, &QColorDialog::currentColorChanged, this, &Data3DTreeDelegate::onEditorEdited); pColorDialog->setWindowTitle("Select Sulci Color"); pColorDialog->show(); return pColorDialog; } case MetaTreeItemTypes::RTDataColormapType: { QComboBox* pComboBox = new QComboBox(parent); connect(pComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &Data3DTreeDelegate::onEditorEdited); pComboBox->addItem("Hot Negative 1"); pComboBox->addItem("Hot Negative 2"); pComboBox->addItem("Hot"); return pComboBox; } case MetaTreeItemTypes::RTDataNormalizationValue: { Spline* pSpline = new Spline("Spline Histogram", 0); connect(pSpline, static_cast<void (Spline::*)(double, double, double)>(&Spline::borderChanged), this, &Data3DTreeDelegate::onEditorEdited); QStandardItem* pParentItem = static_cast<QStandardItem*>(pAbstractItem->QStandardItem::parent()); QModelIndex indexParent = pData3DTreeModel->indexFromItem(pParentItem); MatrixXd matRTData = index.model()->data(indexParent, Data3DTreeModelItemRoles::RTData).value<MatrixXd>(); Eigen::VectorXd resultClassLimit; Eigen::VectorXi resultFrequency; MNEMath::histcounts(matRTData, false, 50, resultClassLimit, resultFrequency, 0.0, 0.0); pSpline->setData(resultClassLimit, resultFrequency, 0); QVector3D vecThresholdValues = index.model()->data(index, MetaTreeItemRoles::RTDataNormalizationValue).value<QVector3D>(); pSpline->setThreshold(vecThresholdValues); AbstractTreeItem* pParentItemAbstract = static_cast<AbstractTreeItem*>(pParentItem); QList<QStandardItem*> pColormapItem = pParentItemAbstract->findChildren(MetaTreeItemTypes::RTDataColormapType); for(int i = 0; i < pColormapItem.size(); ++i) { QModelIndex indexColormapItem = pData3DTreeModel->indexFromItem(pColormapItem.at(i)); QString colorMap = index.model()->data(indexColormapItem, MetaTreeItemRoles::RTDataColormapType).value<QString>(); pSpline->setColorMap(colorMap); } return pSpline; } case MetaTreeItemTypes::RTDataTimeInterval: { QSpinBox* pSpinBox = new QSpinBox(parent); connect(pSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &Data3DTreeDelegate::onEditorEdited); pSpinBox->setSuffix(" mSec"); pSpinBox->setMinimum(17); pSpinBox->setMaximum(50000); pSpinBox->setSingleStep(10); pSpinBox->setValue(index.model()->data(index, MetaTreeItemRoles::RTDataTimeInterval).toInt()); return pSpinBox; } case MetaTreeItemTypes::RTDataVisualizationType: { QComboBox* pComboBox = new QComboBox(parent); pComboBox->addItem("Vertex based"); pComboBox->addItem("Smoothing based"); pComboBox->addItem("Annotation based"); return pComboBox; } case MetaTreeItemTypes::SurfaceColor: { QColorDialog *pColorDialog = new QColorDialog(); connect(pColorDialog, &QColorDialog::currentColorChanged, this, &Data3DTreeDelegate::onEditorEdited); pColorDialog->setWindowTitle("Select Surface Color"); pColorDialog->show(); return pColorDialog; } case MetaTreeItemTypes::PointColor: { QColorDialog *pColorDialog = new QColorDialog(); connect(pColorDialog, &QColorDialog::currentColorChanged, this, &Data3DTreeDelegate::onEditorEdited); pColorDialog->setWindowTitle("Select Point Color"); pColorDialog->show(); return pColorDialog; } case MetaTreeItemTypes::RTDataNumberAverages: { QSpinBox* pSpinBox = new QSpinBox(parent); connect(pSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &Data3DTreeDelegate::onEditorEdited); pSpinBox->setMinimum(1); pSpinBox->setMaximum(100); pSpinBox->setSingleStep(1); pSpinBox->setValue(index.model()->data(index, MetaTreeItemRoles::RTDataNumberAverages).toInt()); return pSpinBox; } case MetaTreeItemTypes::SurfaceAlpha: { QDoubleSpinBox* pDoubleSpinBox = new QDoubleSpinBox(parent); connect(pDoubleSpinBox, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &Data3DTreeDelegate::onEditorEdited); pDoubleSpinBox->setMinimum(0.01); pDoubleSpinBox->setMaximum(1.0); pDoubleSpinBox->setSingleStep(0.01); pDoubleSpinBox->setValue(index.model()->data(index, MetaTreeItemRoles::SurfaceAlpha).toDouble()); return pDoubleSpinBox; } case MetaTreeItemTypes::SurfaceTranslateX: { QDoubleSpinBox* pDoubleSpinBox = new QDoubleSpinBox(parent); connect(pDoubleSpinBox, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &Data3DTreeDelegate::onEditorEdited); pDoubleSpinBox->setMinimum(-10000.0); pDoubleSpinBox->setMaximum(10000.0); pDoubleSpinBox->setSingleStep(0.01); pDoubleSpinBox->setValue(index.model()->data(index, MetaTreeItemRoles::SurfaceTranslateX).toDouble()); return pDoubleSpinBox; } case MetaTreeItemTypes::SurfaceTranslateY: { QDoubleSpinBox* pDoubleSpinBox = new QDoubleSpinBox(parent); connect(pDoubleSpinBox, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &Data3DTreeDelegate::onEditorEdited); pDoubleSpinBox->setMinimum(-10000.0); pDoubleSpinBox->setMaximum(10000.0); pDoubleSpinBox->setSingleStep(0.01); pDoubleSpinBox->setValue(index.model()->data(index, MetaTreeItemRoles::SurfaceTranslateY).toDouble()); return pDoubleSpinBox; } case MetaTreeItemTypes::SurfaceTranslateZ: { QDoubleSpinBox* pDoubleSpinBox = new QDoubleSpinBox(parent); connect(pDoubleSpinBox, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &Data3DTreeDelegate::onEditorEdited); pDoubleSpinBox->setMinimum(-10000.0); pDoubleSpinBox->setMaximum(10000.0); pDoubleSpinBox->setSingleStep(0.01); pDoubleSpinBox->setValue(index.model()->data(index, MetaTreeItemRoles::SurfaceTranslateZ).toDouble()); return pDoubleSpinBox; } case MetaTreeItemTypes::NetworkThreshold: { Spline* pSpline = new Spline("Spline Histogram", 0); connect(pSpline, static_cast<void (Spline::*)(double, double, double)>(&Spline::borderChanged), this, &Data3DTreeDelegate::onEditorEdited); QStandardItem* pParentItem = static_cast<QStandardItem*>(pAbstractItem->QStandardItem::parent()); QModelIndex indexParent = pData3DTreeModel->indexFromItem(pParentItem); MatrixXd matRTData = index.model()->data(indexParent, Data3DTreeModelItemRoles::NetworkDataMatrix).value<MatrixXd>(); Eigen::VectorXd resultClassLimit; Eigen::VectorXi resultFrequency; MNEMath::histcounts(matRTData, false, 50, resultClassLimit, resultFrequency, 0.0, 0.0); pSpline->setData(resultClassLimit, resultFrequency, 0); QVector3D vecThresholdValues = index.model()->data(index, MetaTreeItemRoles::NetworkThreshold).value<QVector3D>(); pSpline->setThreshold(vecThresholdValues); return pSpline; } case MetaTreeItemTypes::NetworkMatrix: { QStandardItem* pParentItem = static_cast<QStandardItem*>(pAbstractItem->QStandardItem::parent()); QModelIndex indexParent = pData3DTreeModel->indexFromItem(pParentItem); MatrixXd matRTData = index.model()->data(indexParent, Data3DTreeModelItemRoles::NetworkDataMatrix).value<MatrixXd>(); ImageSc* pPlotLA = new ImageSc(matRTData); pPlotLA->show(); //return pPlotLA; } default: // do nothing; break; } return QItemDelegate::createEditor(parent, option, index); }
void testCommon(const Spline &sp, const double *x, const double *y) { static double eps = 1e-10; static double epsFD = 1e-7; size_t n = sp.numSamples(); for (size_t i = 0; i < n; ++i) { // sure that we hit all sampling points double y0 = (i>0)?sp.eval(x[i]-eps):y[0]; double y1 = sp.eval(x[i]); double y2 = (i<n-1)?sp.eval(x[i]+eps):y[n-1]; if (std::abs(y0 - y[i]) > 100*eps || std::abs(y2 - y[i]) > 100*eps) OPM_THROW(std::runtime_error, "Spline seems to be discontinuous at sampling point " << i << "!"); if (std::abs(y1 - y[i]) > eps) OPM_THROW(std::runtime_error, "Spline does not capture sampling point " << i << "!"); // make sure the derivative is continuous (assuming that the // second derivative is smaller than 1000) double d1 = sp.evalDerivative(x[i]); double d0 = (i>0)?sp.evalDerivative(x[i]-eps):d1; double d2 = (i<n-1)?sp.evalDerivative(x[i]+eps):d1; if (std::abs(d1 - d0) > 1000*eps || std::abs(d2 - d0) > 1000*eps) OPM_THROW(std::runtime_error, "Spline seems to exhibit a discontinuous derivative at sampling point " << i << "!"); } // make sure the derivatives are consistent with the curve size_t np = 3*n; for (size_t i = 0; i < np; ++i) { double xMin = sp.xAt(0); double xMax = sp.xAt(sp.numSamples() - 1); double xval = xMin + (xMax - xMin)*i/np; // first derivative double y1 = sp.eval(xval+epsFD); double y0 = sp.eval(xval); double mFD = (y1 - y0)/epsFD; double m = sp.evalDerivative(xval); if (std::abs( mFD - m ) > 1000*epsFD) OPM_THROW(std::runtime_error, "Derivative of spline seems to be inconsistent with cuve" " (" << mFD << " - " << m << " = " << mFD - m << ")!"); // second derivative y1 = sp.evalDerivative(xval+epsFD); y0 = sp.evalDerivative(xval); mFD = (y1 - y0)/epsFD; m = sp.evalSecondDerivative(xval); if (std::abs( mFD - m ) > 1000*epsFD) OPM_THROW(std::runtime_error, "Second derivative of spline seems to be inconsistent with cuve" " (" << mFD << " - " << m << " = " << mFD - m << ")!"); // Third derivative y1 = sp.evalSecondDerivative(xval+epsFD); y0 = sp.evalSecondDerivative(xval); mFD = (y1 - y0)/epsFD; m = sp.evalThirdDerivative(xval); if (std::abs( mFD - m ) > 1000*epsFD) OPM_THROW(std::runtime_error, "Third derivative of spline seems to be inconsistent with cuve" " (" << mFD << " - " << m << " = " << mFD - m << ")!"); } }
void Data3DTreeDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { const Data3DTreeModel* pData3DTreeModel = static_cast<const Data3DTreeModel*>(index.model()); const AbstractTreeItem* pAbstractItem = static_cast<const AbstractTreeItem*>(pData3DTreeModel->itemFromIndex(index)); switch(pAbstractItem->type()) { case MetaTreeItemTypes::SurfaceColorGyri: { QColorDialog* pColorDialog = static_cast<QColorDialog*>(editor); QColor color = pColorDialog->currentColor(); QVariant data; data.setValue(color); model->setData(index, data, MetaTreeItemRoles::SurfaceColorGyri); model->setData(index, data, Qt::DecorationRole); return; } case MetaTreeItemTypes::SurfaceColorSulci: { QColorDialog* pColorDialog = static_cast<QColorDialog*>(editor); QColor color = pColorDialog->currentColor(); QVariant data; data.setValue(color); model->setData(index, data, MetaTreeItemRoles::SurfaceColorSulci); model->setData(index, data, Qt::DecorationRole); return; } case MetaTreeItemTypes::RTDataColormapType: { QComboBox* pColorMapType = static_cast<QComboBox*>(editor); QVariant data; data.setValue(pColorMapType->currentText()); model->setData(index, data, MetaTreeItemRoles::RTDataColormapType); model->setData(index, data, Qt::DisplayRole); return; } case MetaTreeItemTypes::RTDataNormalizationValue: { Spline* pSpline = static_cast<Spline*>(editor); QVector3D returnVector; returnVector = pSpline->getThreshold(); QString displayThreshold; displayThreshold = QString("%1,%2,%3").arg(returnVector.x()).arg(returnVector.y()).arg(returnVector.z()); QVariant dataDisplay; dataDisplay.setValue(displayThreshold); model->setData(index, dataDisplay, Qt::DisplayRole); model->setData(index, returnVector, MetaTreeItemRoles::RTDataNormalizationValue); return; } case MetaTreeItemTypes::RTDataTimeInterval: { QSpinBox* pSpinBox = static_cast<QSpinBox*>(editor); QVariant data; data.setValue(pSpinBox->value()); model->setData(index, data, MetaTreeItemRoles::RTDataTimeInterval); model->setData(index, data, Qt::DisplayRole); break; } case MetaTreeItemTypes::RTDataVisualizationType: { QComboBox* pVisType = static_cast<QComboBox*>(editor); QVariant data; data.setValue(pVisType->currentText()); model->setData(index, data, MetaTreeItemRoles::RTDataVisualizationType); model->setData(index, data, Qt::DisplayRole); return; } case MetaTreeItemTypes::SurfaceColor: { QColorDialog* pColorDialog = static_cast<QColorDialog*>(editor); QColor color = pColorDialog->currentColor(); QVariant data; data.setValue(color); model->setData(index, data, MetaTreeItemRoles::SurfaceColor); model->setData(index, data, Qt::DecorationRole); return; } case MetaTreeItemTypes::PointColor: { QColorDialog* pColorDialog = static_cast<QColorDialog*>(editor); QColor color = pColorDialog->currentColor(); QVariant data; data.setValue(color); model->setData(index, data, MetaTreeItemRoles::PointColor); model->setData(index, data, Qt::DecorationRole); return; } case MetaTreeItemTypes::RTDataNumberAverages: { QSpinBox* pSpinBox = static_cast<QSpinBox*>(editor); QVariant data; data.setValue(pSpinBox->value()); model->setData(index, data, MetaTreeItemRoles::RTDataNumberAverages); model->setData(index, data, Qt::DisplayRole); break; } case MetaTreeItemTypes::SurfaceAlpha: { QDoubleSpinBox* pDoubleSpinBox = static_cast<QDoubleSpinBox*>(editor); QVariant data; data.setValue(pDoubleSpinBox->value()); model->setData(index, data, MetaTreeItemRoles::SurfaceAlpha); model->setData(index, data, Qt::DisplayRole); break; } case MetaTreeItemTypes::SurfaceTranslateX: { QDoubleSpinBox* pDoubleSpinBox = static_cast<QDoubleSpinBox*>(editor); QVariant data; data.setValue(pDoubleSpinBox->value()); model->setData(index, data, MetaTreeItemRoles::SurfaceTranslateX); model->setData(index, data, Qt::DisplayRole); break; } case MetaTreeItemTypes::SurfaceTranslateY: { QDoubleSpinBox* pDoubleSpinBox = static_cast<QDoubleSpinBox*>(editor); QVariant data; data.setValue(pDoubleSpinBox->value()); model->setData(index, data, MetaTreeItemRoles::SurfaceTranslateY); model->setData(index, data, Qt::DisplayRole); break; } case MetaTreeItemTypes::SurfaceTranslateZ: { QDoubleSpinBox* pDoubleSpinBox = static_cast<QDoubleSpinBox*>(editor); QVariant data; data.setValue(pDoubleSpinBox->value()); model->setData(index, data, MetaTreeItemRoles::SurfaceTranslateZ); model->setData(index, data, Qt::DisplayRole); break; } case MetaTreeItemTypes::NetworkThreshold: { Spline* pSpline = static_cast<Spline*>(editor); QVector3D returnVector; returnVector = pSpline->getThreshold(); QString displayThreshold; displayThreshold = QString("%1,%2,%3").arg(returnVector.x()).arg(returnVector.y()).arg(returnVector.z()); QVariant dataDisplay; dataDisplay.setValue(displayThreshold); model->setData(index, dataDisplay, Qt::DisplayRole); model->setData(index, returnVector, MetaTreeItemRoles::NetworkThreshold); return; } default: // do nothing; break; } QItemDelegate::setModelData(editor, model, index); }