안드로이드 그래픽 구현을 위한 베지에 곡선(Bézier Curve) 완벽 가이드

베지에 곡선 개요

베지에 곡선은 컴퓨터 그래픽스에서 매끄러운 곡선을 그리기 위해 널리 사용되는 수학적 모델입니다. 안드로이드 개발에서는 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를 제공할 수 있습니다.

태그: Android canvas BezierCurve CustomView Graphics

7월 29일 22:43에 게시됨