Bezier curve
베지에 곡선 혹은 베지어 곡선(Bézier Curve)은 n개의 점으로부터 얻어지는 n-1차 곡선으로 수치 해석 분야에서 상당히 중요한 위치를 차지하고 있다. 특히 3차 베지에 곡선은 포스트스크립트 글꼴, 메타폰트(METAFONT), 김프 등에서 부드러운 곡선을 생성하는 데에 이용되고 있으며, 트루 타입 폰트에는 2차 베지에 곡선 알고리즘을 사용한다.
in HTML5
HTML:canvas#quadraticCurveTo와 HTML:canvas#bezierCurveTo API 참조. 각각 2차, 3차 베지어 곡선이다.
구현 방법
godot으로 구현한 내용이다. 참고로 사용 언어는 C# 이다.
Quadratic Bezier
Godot_-_bezier_quadratic_points.png
private List<Vector2> QuadraticBezierPoints(Vector2 p0, Vector2 p1, Vector2 p2, float step, bool ignoreStart = false, bool ignoreStop = false)
{
Debug.Assert(0 < step && step <= 1);
var cursor = step;
var result = new List<Vector2>();
if (!ignoreStart)
{
result.Add(QuadraticBezier(p0, p1, p2, 0));
}
while (cursor < 1)
{
result.Add(QuadraticBezier(p0, p1, p2, cursor));
cursor += step;
}
if (!ignoreStop)
{
result.Add(QuadraticBezier(p0, p1, p2, 1));
}
return result;
}
private Vector2 QuadraticBezier(Vector2 p0, Vector2 p1, Vector2 p2, float t)
{
var q0 = p0.LinearInterpolate(p1, t);
var q1 = p1.LinearInterpolate(p2, t);
return q0.LinearInterpolate(q1, t);
}
출력 결과:
Godot_-_bezier_quadratic_points.gif
Cubic Bezier
Godot_-_bezier_cubic_points.png
private List<Vector2> CubicBezierPoints(Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3, float step, bool ignoreStart = false, bool ignoreStop = false)
{
Debug.Assert(0 < step && step <= 1);
var cursor = step;
var result = new List<Vector2>();
if (!ignoreStart)
{
result.Add(CubicBezier(p0, p1, p2, p3, 0));
}
while (cursor < 1)
{
result.Add(CubicBezier(p0, p1, p2, p3, cursor));
cursor += step;
}
if (!ignoreStop)
{
result.Add(CubicBezier(p0, p1, p2, p3, 1));
}
return result;
}
private Vector2 CubicBezier(Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3, float t)
{
var q0 = p0.LinearInterpolate(p1, t);
var q1 = p1.LinearInterpolate(p2, t);
var q2 = p2.LinearInterpolate(p3, t);
var r0 = q0.LinearInterpolate(q1, t);
var r1 = q1.LinearInterpolate(q2, t);
return r0.LinearInterpolate(r1, t);
}
출력 결과:
Godot_-_bezier_cubic_points.gif
참고로 Vector2의 LinearInterpolate 함수 구현체는 다음과 같다:
Vector2 linear_interpolate(const Vector2 &p_a, const Vector2 &p_b, real_t p_t)
{
Vector2 res = p_a;
res.x += (p_t * (p_b.x - p_a.x));
res.y += (p_t * (p_b.y - p_a.y));
return res;
}
De Casteljau's algorithm
Casteljau 알고리즘은 베지어 곡선을 계산하는 기법으로, 주어진 제어점을 사용해 곡선 상의 점을 반복적으로 보간(interpolation)하는 방식입니다.
DEFAULT_CURVE_TESSELLATION_TOL: Final[float] = 1.25
"""
Tessellation tolerance when using BezierCurve without a specific number of segments.
Decrease for highly tessellated curves (higher quality, more polygons),
Increase to reduce quality.
"""