// This is a binary search algorithm that we // need to use to find the Y value that // corresponds with our given X value. // inputXValue is the target value here. // This function only works if the Bezier curve // does not have multiple Y values for any // given X value, so make sure that the // control points of the Bezier curve stay // inside the bounds of the end points. double BezierCurve::getOutput (double inputXValue) { double totalNumberOfSamples = mPointD.xValue; double xTolerance = 1.0 / totalNumberOfSamples; double lowerBound = 0.0; double upperBound = 1.0; double currentPositionInTime = 0.5; double currentXValue = getPointOnCurve (currentPositionInTime).xValue; while (std::abs (inputXValue - currentXValue) > xTolerance) { if (inputXValue > currentXValue) lowerBound = currentPositionInTime; else upperBound = currentPositionInTime; currentPositionInTime = (lowerBound + upperBound) * 0.5; currentXValue = getPointOnCurve (currentPositionInTime).xValue; } return getPointOnCurve (currentPositionInTime).yValue; }
void BezierCurve::createVAO() { if(m_vaoCurve!=0 && m_vaoPoints!=0) { m_vaoCurve->unbind(); m_vaoCurve->removeVOA(); delete m_vaoCurve; m_vaoPoints->unbind(); m_vaoPoints->removeVOA(); delete m_vaoPoints; } m_vaoPoints=VertexArrayObject::createVOA(GL_POINTS); m_vaoPoints->bind(); unsigned int size=m_cp.size(); std::vector <Vec3> points(size); for(unsigned int i=0;i<size;++i) { points[i].set(m_cp[i]); } m_vaoPoints->setData(m_numCP*sizeof(Vec3),points[0].m_x); m_vaoPoints->setNumIndices(m_numCP); m_vaoPoints->setVertexAttributePointer(0,3,GL_FLOAT,0,0); m_vaoPoints->unbind(); m_vaoCurve=VertexArrayObject::createVOA(GL_LINE_STRIP); m_vaoCurve->bind(); std::vector <Vec3> lines(m_lod); for(int i=0;i!=m_lod;++i) { Real t = m_knots[m_numKnots-1] * i / (Real)(m_lod-1); if(i==m_lod-1) { t-=0.001f; } lines[i].set(getPointOnCurve(t)); } m_vaoCurve->setData(m_lod*sizeof(Vec3),lines[0].m_x); m_vaoCurve->setNumIndices(m_lod); m_vaoCurve->setVertexAttributePointer(0,3,GL_FLOAT,0,0); m_vaoCurve->unbind(); }
void BezierCurve::createVAO() noexcept { if(m_vaoCurve!=0 && m_vaoPoints!=0) { m_vaoCurve->unbind(); m_vaoCurve->removeVAO(); //delete m_vaoCurve; m_vaoPoints->unbind(); m_vaoPoints->removeVAO(); //delete m_vaoPoints; } m_vaoPoints=ngl::VAOFactory::createVAO("simpleVAO",GL_POINTS); m_vaoPoints->bind(); size_t size=m_cp.size(); std::vector <Vec3> points(size); for(size_t i=0;i<size;++i) { points[i].set(m_cp[i]); } m_vaoPoints->setData(SimpleVAO::VertexData(m_numCP*sizeof(Vec3),points[0].m_x)); m_vaoPoints->setNumIndices(m_numCP); m_vaoPoints->setVertexAttributePointer(0,3,GL_FLOAT,0,0); m_vaoPoints->unbind(); m_vaoCurve=ngl::VAOFactory::createVAO("simpleVAO",GL_LINE_STRIP); m_vaoCurve->bind(); std::vector <Vec3> lines(m_lod); for(unsigned int i=0;i!=m_lod;++i) { Real t = m_knots[m_numKnots-1] * i / static_cast<Real>(m_lod-1); if(i==m_lod-1) { t-=0.001f; } lines[i].set(getPointOnCurve(t)); } m_vaoCurve->setData(SimpleVAO::VertexData(m_lod*sizeof(Vec3),lines[0].m_x)); m_vaoCurve->setNumIndices(m_lod); m_vaoCurve->setVertexAttributePointer(0,3,GL_FLOAT,0,0); m_vaoCurve->unbind(); }