// constructs curve for v parameter BezierCurve _ConstructCurve_Y(float u) const { Points::value_type subCurves(controlpoints_.size()); auto control_iter = controlpoints_.begin(); for (Points::value_type::iterator sub_iter = subCurves.begin(); sub_iter != subCurves.end(); ++sub_iter,++control_iter) { *sub_iter = BezierCurve(*control_iter).GetPoint(u); } return BezierCurve(subCurves); }
// constructs curve for u parameter // more expensive since parameters are saved x major BezierCurve _ConstructCurve_X(float v) const { Points::value_type subCurves(controlpoints_[0].size()); Points::value_type tmp(controlpoints_.size()); for (int j = 0;j < subCurves.size();++j) { for (int i = 0;i < controlpoints_.size(); ++i) tmp.at(i) = controlpoints_[i][j]; subCurves[j] = BezierCurve(tmp).GetPoint(v); } return BezierCurve(subCurves); }
Vector3f BezierPatch::evaluate(Vector2f u) { Vector3f p[4]; for (int i = 0; i < 4; i++) { p[i] = curves[i].evaluate(u(0)); } return (BezierCurve(p)).evaluate(u(1)); }
std::shared_ptr<CSG> BezierCurve(const Vector & v1, const Vector & v2, const Vector & v3, const float delta) { std::vector<Vector> vv; vv.push_back(v1); vv.push_back(v2); vv.push_back(v3); return BezierCurve(vv, delta); }
/// Derivative BezierCurve. /// \details The derivative curve is exactly the tangent for every point. /// This value might not be correct for \f$ t = 0 \f$ and \f$ t = 1 \f$. /// \return Returns the derivative curve. BezierCurve GetTangentCurve() const { Points derivate_array; float n = static_cast<float>(controlpoints_.size() - 1); for (auto iter = controlpoints_.begin(); iter+1 != controlpoints_.end(); ++iter) { derivate_array.push_back(n * (*(iter + 1) - *iter)); } return BezierCurve(derivate_array); }
BezierCurve BezierCurve::getDerivative() const { if (getDegree() < 1) throw Exception("Cannot derive a curve of degree < 1."); // actually we can, it just doesn't make any sense. vector<Vector> forward_differences(controlPoints.size()-1); float degree = float(getDegree()); for (size_t i = 0; i < forward_differences.size(); ++i) forward_differences[i] = (controlPoints[i+1] - controlPoints[i]) * degree; return BezierCurve(forward_differences); }
static void BuildCurves(float3* points, int count, bool isClosed, std::vector<BezierCurve>* out) { assert(count > 1); float3 cp[4]; if(count == 2) { cp[0] = points[0]; cp[3] = points[1]; cp[1] = cp[0] + 0.3333f * (cp[3] - cp[0]); cp[2] = cp[0] + 0.6666f * (cp[3] - cp[0]); out->push_back(BezierCurve(cp)); } else { float3 zerov(0.0f,0.0f,0.0f); std::vector<float3> tangents(count,zerov); CalcPointTangents(points,&tangents[0],count,isClosed); for (int i = 1; i < count; i++) { float3 chord = points[i] - points[i - 1]; float segLen = length(chord) * 0.3333f; cp[0] = points[i - 1]; cp[3] = points[i]; float3 tangent1 = tangents[i - 1]; if (dot(chord, tangent1) < 0) tangent1 = -tangent1; cp[1] = cp[0] + (tangent1 * segLen); float3 tangent2 = tangents[i]; if (dot(-chord, tangent2) < 0) tangent2 = -tangent2; cp[2] = cp[3] + (tangent2 * segLen); BezierCurve curve(cp); out->push_back(curve); } // Calculate last curve if is closed if (isClosed) { float3 lastcp1 = cp[1]; float3 lastcp2 = cp[2]; cp[0] = points[count - 1]; cp[3] = points[0]; BezierCurve lastCurve = out->back(); float tanLen = length(cp[3] - cp[0]) * 0.3333f; float3 v = normalize(lastCurve.GetControlPoint(2) - cp[0]); cp[1] = cp[0] - (v * tanLen); BezierCurve firstCurve = out->front(); v = normalize(firstCurve.GetControlPoint(1) - cp[3]); cp[2] = cp[3] - (v * tanLen); BezierCurve curve(cp); out->push_back(curve); } } }