Ejemplo n.º 1
0
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());
}
Ejemplo n.º 2
0
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;
				}
			}
		}
	}
}