예제 #1
0
void BsplineCurveEvaluator::evaluateCurve(const vector<Point> &control_points,
		vector<Point> &evaluated_curve_points, const float &animation_length,
		const bool &wrap_control_points) const
{
	evaluated_curve_points.clear();

	vector<Point> cps_;
	if (wrap_control_points)
	{
		cps_.push_back(Point((control_points.end() - 2)->x - animation_length,
				(control_points.end() - 2)->y));
		cps_.push_back(Point(control_points.back().x - animation_length,
				control_points.back().y));
		cps_.insert(cps_.end(), control_points.begin(), control_points.end());
		cps_.push_back(Point(control_points.front().x + animation_length,
				control_points.front().y));
		cps_.push_back(Point((control_points.begin() + 1)->x + animation_length,
				(control_points.begin() + 1)->y));
	}
	else
	{
		cps_.push_back(control_points.front());
		cps_.push_back(control_points.front());
		cps_.insert(cps_.end(), control_points.begin(), control_points.end());
		cps_.push_back(control_points.back());
		cps_.push_back(control_points.back());
	}

	static const Mat4d m = Mat4d(1, 4, 1, 0, 0, 4, 2, 0, 0, 2, 4, 0, 0, 1, 4, 1)
			/ 6.0;
	BezierCurveEvaluator bce;
	for (size_t cp = 0; cp + 3 < cps_.size(); ++cp)
	{
		const Vec4d bx_vec(cps_[cp].x, cps_[cp + 1].x, cps_[cp + 2].x,
				cps_[cp + 3].x);
		const Vec4d by_vec(cps_[cp].y, cps_[cp + 1].y, cps_[cp + 2].y,
				cps_[cp + 3].y);
		Vec4d vx_vec = m * bx_vec;
		Vec4d vy_vec = m * by_vec;
		vector<Point> vps;
		for (int i = 0; i < 4; ++i)
		{
			vps.push_back(Point(vx_vec[i], vy_vec[i]));
		}

		vector<Point> evaluated;
		bce.evaluateCurve(vps, evaluated, animation_length, false);
		// Remove the edge points
		evaluated_curve_points.insert(evaluated_curve_points.end(),
				evaluated.begin(), evaluated.end() - 2);
	}

	if (!wrap_control_points)
	{
		evaluated_curve_points.push_back(Point(0, control_points[0].y));
		evaluated_curve_points.push_back(Point(animation_length,
				control_points.back().y));
	}
}
예제 #2
0
void BSplineCurveEvaluator::evaluateCurve(
	const std::vector<Point>& controlPoints,
	std::vector<Point>& evaluatedPoints,
	const float& animationLength,
	const bool& beWrap) const
{
	evaluatedPoints.clear();

	if (!beWrap) 
	{
		evaluatedPoints.push_back(Point(0, controlPoints.front().y));
		evaluatedPoints.push_back(Point(animationLength, controlPoints.back().y));
	}
	
	// a hack to make the endpoints controllable
	vector<Point> controlPointsCopy;
	if (beWrap) 
	{
		Point start_p1 = Point((controlPoints.end() - 2)->x - animationLength,
			(controlPoints.end() - 2)->y);
		Point start_p2 = Point((controlPoints.end() - 1)->x - animationLength,
			(controlPoints.end() - 1)->y);
		Point end_p1 = Point((controlPoints.begin())->x + animationLength,
			(controlPoints.begin())->y);
		Point end_p2 = Point((controlPoints.begin() + 1)->x + animationLength,
			(controlPoints.begin() + 1)->y);
		controlPointsCopy.push_back(start_p1);
		controlPointsCopy.push_back(start_p2);
		controlPointsCopy.insert(controlPointsCopy.end(), controlPoints.begin(), controlPoints.end());
		controlPointsCopy.push_back(end_p1);
		controlPointsCopy.push_back(end_p2);
	}
	else
	{
		controlPointsCopy.push_back(controlPoints.front());
		controlPointsCopy.push_back(controlPoints.front());
		controlPointsCopy.insert(controlPointsCopy.end(), controlPoints.begin(), controlPoints.end());
		controlPointsCopy.push_back(controlPoints.back());
		controlPointsCopy.push_back(controlPoints.back());
	}
	const Mat4d basis = Mat4d(
		1, 4, 1, 0,
		0, 4, 2, 0,
		0, 2, 4, 0,
		0, 1, 4, 1) / 6.0;

	BezierCurveEvaluator bezierCurveEvaluator;
	for (size_t cnt = 0; cnt + 3 < controlPointsCopy.size(); ++cnt)
	{
		Vec4d param_x(controlPointsCopy[cnt].x, controlPointsCopy[cnt + 1].x,
			controlPointsCopy[cnt + 2].x, controlPointsCopy[cnt + 3].x);
		Vec4d param_y(controlPointsCopy[cnt].y, controlPointsCopy[cnt + 1].y,
			controlPointsCopy[cnt + 2].y, controlPointsCopy[cnt + 3].y);
		param_x = basis * param_x;
		param_y = basis * param_y;
		vector<Point> param_control;
		for (int i = 0; i < 4; ++i)
		{
			param_control.push_back(Point(param_x[i], param_y[i]));
		}
		vector<Point> param_evaluated;
		bezierCurveEvaluator.evaluateCurve(param_control, param_evaluated, animationLength, false);
		evaluatedPoints.insert(evaluatedPoints.end(), param_evaluated.begin(), param_evaluated.end()-2);
	}

}