베지에 곡선 개요
베지에 곡선은 컴퓨터 그래픽스에서 매끄러운 곡선을 그리기 위해 널리 사용되는 수학적 모델입니다. 안드로이드 개발에서는 Path 클래스의 메서드를 통해 이를 쉽게 구현할 수 있으며, 복잡한 UI 애니메이션이나 부드러운 드로잉 기능을 만들 때 필수적으로 사용됩니다.
1차 베지에 곡선 (Linear Bézier Curve)
1차 베지에 곡선은 두 개의 점(시작점과 끝점)을 연결하는 단순한 직선입니다. 안드로이드의 lineTo() 메서드와 동일한 역할을 수행합니다.
2차 베지에 곡선 (Quadratic Bézier Curve)
2차 베지에 곡선은 시작점, 하나의 제어점, 그리고 끝점까지 총 3개의 점으로 구성됩니다. 제어점의 위치에 따라 곡선의 휘어짐 정도가 결정됩니다. 수학적으로는 각 선분 간의 비율이 일정하게 유지되는 자취를 따라 그려집니다.
안드로이드에서는 quadTo() 메서드를 사용합니다.
Path path = new Path();
// 시작점 설정
path.moveTo(startX, startY);
// 제어점(cpX, cpY)과 끝점(endX, endY) 설정
path.quadTo(cpX, cpY, endX, endY);
canvas.drawPath(path, paint);
실시간 제어점 이동 예제
터치 이벤트를 통해 제어점의 위치를 실시간으로 변경하며 곡선을 그리는 커스텀 뷰 예제입니다.
public class QuadraticCurveView extends View {
private float controlX, controlY;
private Paint curvePaint;
private Paint pointPaint;
public QuadraticCurveView(Context context, AttributeSet attrs) {
super(context, attrs);
curvePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
curvePaint.setStyle(Paint.Style.STROKE);
curvePaint.setStrokeWidth(8);
pointPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
pointPaint.setColor(Color.RED);
pointPaint.setStrokeWidth(20);
}
@Override
protected void onDraw(Canvas canvas) {
Path path = new Path();
path.moveTo(100, 500); // 시작점
path.quadTo(controlX, controlY, 900, 500); // 제어점과 끝점
canvas.drawPath(path, curvePaint);
canvas.drawPoint(controlX, controlY, pointPaint); // 제어점 시각화
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_MOVE) {
controlX = event.getX();
controlY = event.getY();
invalidate();
}
return true;
}
}
3차 베지에 곡선 (Cubic Bézier Curve)
3차 베지에 곡선은 시작점과 끝점 외에 두 개의 제어점을 가집니다. 두 개의 제어점을 통해 더 정교하고 복잡한 형태의 곡선을 표현할 수 있습니다. 안드로이드 Path 클래스에서는 cubicTo() 메서드를 사용합니다.
// 시작점은 moveTo로 설정
path.moveTo(x1, y1);
// 제어점1(cx1, cy1), 제어점2(cx2, cy2), 끝점(x2, y2)
path.cubicTo(cx1, cy1, cx2, cy2, x2, y2);
복합 제어점 활용 예제
두 개의 제어점을 관리하는 간단한 로직을 포함한 예제 코드입니다.
public class CubicCurveView extends View {
private PointF cp1 = new PointF(200, 200);
private PointF cp2 = new PointF(600, 800);
private boolean toggleFlag = false;
public void switchControlPoint() {
toggleFlag = !toggleFlag;
}
@Override
protected void onDraw(Canvas canvas) {
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(10);
Path cubicPath = new Path();
cubicPath.moveTo(100, 500);
cubicPath.cubicTo(cp1.x, cp1.y, cp2.x, cp2.y, 900, 500);
paint.setColor(Color.BLUE);
canvas.drawPath(cubicPath, paint);
// 제어점 표시
paint.setStrokeWidth(25);
paint.setColor(Color.RED);
canvas.drawPoint(cp1.x, cp1.y, paint);
paint.setColor(Color.GREEN);
canvas.drawPoint(cp2.x, cp2.y, paint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (!toggleFlag) {
cp1.set(event.getX(), event.getY());
} else {
cp2.set(event.getX(), event.getY());
}
invalidate();
}
return true;
}
}
요약 및 활용
베지에 곡선은 안드로이드 커스텀 뷰 제작 시 다음과 같은 상황에서 자주 사용됩니다.
- 부드러운 데이터 그래프(Chart)의 연결선 구현
- 물결 효과(Wave Effect) 및 로딩 애니메이션
- 자유 곡선 드로잉 앱 기능
- 정교한 벡터 아이콘 렌더링
각 곡선의 제어점 위치를 수학적으로 계산하거나 터치 인터랙션과 연결하면 사용자에게 훨씬 부드럽고 직관적인 UI를 제공할 수 있습니다.