void BezierBoundarySolver::_Sample5thOrderBezier(BezierBoundaryProblem* pProblem) { Eigen::Vector6d coefs, dCoefs, ddCoefs; double dt = 1.0/pProblem->m_nDiscretization; pProblem->m_vCurvatures.clear(); pProblem->m_vDistances.clear(); pProblem->m_vPts.clear(); pProblem->m_vCurvatures.reserve(pProblem->m_nDiscretization+1); pProblem->m_vDistances.reserve(pProblem->m_nDiscretization+1); pProblem->m_vPts.reserve(pProblem->m_nDiscretization+1); pProblem->m_dDistance = 0; Eigen::Vector2d lastPt(pProblem->m_xVals[0],pProblem->m_yVals[0]); double t = 0; for(int ii = 0 ; ii <= pProblem->m_nDiscretization ; ii++) { _GetCoefs(coefs,dCoefs,ddCoefs,t); //calculate the x and y position of the curve at this t pProblem->m_vPts.push_back(Eigen::Vector2d(coefs.transpose()*pProblem->m_xVals, coefs.transpose()*pProblem->m_yVals)); pProblem->m_dDistance += (lastPt - pProblem->m_vPts.back()).norm(); lastPt = pProblem->m_vPts.back(); //calculate the derivatives of x and y double dX = dCoefs.transpose()*pProblem->m_xVals; double ddX = ddCoefs.transpose()*pProblem->m_xVals; double dY = dCoefs.transpose()*pProblem->m_yVals; double ddY = ddCoefs.transpose()*pProblem->m_yVals; //and now calculate the curvature double sq = sqrt(powi(dX*dX + dY*dY,3)); //(dX^2+dY^2)^(3/2) double curvature = (dX*ddY-dY*ddX)/sq; pProblem->m_vCurvatures.push_back(curvature*pProblem->m_dAggressiveness); //k = (dX*ddY - dY*ddX)/((dX^2 + dY^2)^(3/2)) pProblem->m_vDistances.push_back(pProblem->m_dDistance); t += dt; } //dout("Sampling bezier. Final point " << pProblem->m_vPts.back().transpose()); }
void FlowData::load() { if(!mReady) { Timer timer(true); XmlDocument * pointsDoc = new XmlDocument(dataSource); XmlElement rootNode = pointsDoc->rootNode(); if(rootNode.hasChildren()) { XmlElement tagNode = rootNode.findChild("tag"); XmlElement drawingNode = tagNode.findChild("drawing"); // Now get all the drawingNode's children.. and only worry about the stroke nodes. if(drawingNode.hasChildren()) { std::vector<XmlElement> strokeNodes = drawingNode.children(); // std::vector<XmlElement> strokeNodes = rootNode.xpath("//tag/drawing//stroke"); if(strokeNodes.size() > 0) { int totalPoints = 0; // Now declare some variables to reuse in our loop. FlowPoint lastPt(Vec2f::zero(), Vec2f::zero(), -1.f); for(std::vector<XmlElement>::iterator it = strokeNodes.begin(); it < strokeNodes.end(); it++) { XmlElement strokeNode = *it; if(strokeNode.name() == "stroke") { // Get all the point nodes. std::vector<XmlElement> pointNodes = strokeNode.children(); // Create a new stroke std::vector<FlowPoint> * stroke = new std::vector<FlowPoint>; for(std::vector<XmlElement>::iterator it2 = pointNodes.begin(); it2 < pointNodes.end(); it2++) { XmlElement ptNode = *it2; if(ptNode.name() == "pt") { std::string xVal = ptNode.findChild("x").value(); // float x = fromString( xVal ); float x = boost::lexical_cast<float>( xVal ); std::string yVal = ptNode.findChild("y").value(); // float y = fromString( yVal ); float y = boost::lexical_cast<float>( yVal ); std::string timeVal = ptNode.findChild("time").value(); // float time = fromString( timeVal ); float time = boost::lexical_cast<float>( timeVal ); x = mRemapMinX + (mRemapMaxX - mRemapMinX) * x; y = mRemapMinY + (mRemapMaxY - mRemapMinY) * y; Vec2f pos(x, y); Vec2f vel; if(lastPt.time > -1) { vel.x = pos.x - lastPt.getX(); vel.y = pos.y - lastPt.getY(); } FlowPoint pt(pos, vel, time); bool shouldAddPoint = false; if(ignoreRedundantPositions == true) { if(lastPt.time > -1) { if(pt.getX() != lastPt.getX() && pt.getY() != lastPt.getY()) { shouldAddPoint = true; } } else { shouldAddPoint = true; } } else { shouldAddPoint = true; } if(shouldAddPoint) { totalPoints++; stroke->push_back(pt); lastPt = FlowPoint(pt.pos, pt.vel, pt.time); } } } // Now see if our stroke is long enough. if(stroke->size() > minNumberOfPointsInStroke) { mStrokes.push_back(stroke); } } } // We're done. timer.stop(); std::cout << "FlowData :: GML file parsing complete. Elapsed seconds: " << toString( timer.getSeconds() ) << std::endl; std::cout << "FlowData :: Total number of points: " << totalPoints << std::endl; std::cout << "FlowData :: Number of strokes: " << mStrokes.size() << std::endl; if(mStrokes.size() > 0) mReady = true; } } } } }