自定义view-一百来行搞定贝塞尔曲线

首先还是上图这次又跟上次一样图片处理的很恶心很丑大家凑活着看吧效果如下
贝塞尔曲线
首先看代码

public class BezierView extends View {
    private PointF clickPoint;//手指按下的点
    private PointF movePoint;//随手指移动的点

    private float clickRadius = 10;//固定圆的半径
    private float clickMinRadius = 3;//固定圆最小的半径
    private float clickMaxRadius = 10;//固定圆最大的半径

    private float moveRadius = 10;//移动圆的半径
    private Paint paint;//画笔

    public BezierView(Context context) {
        this(context, null);
    }

    public BezierView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public BezierView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        paint = new Paint();
        paint.setColor(Color.RED);
        paint.setAntiAlias(true);
        paint.setDither(true);

        clickRadius = dp2px(clickRadius);
        clickMinRadius = dp2px(clickMinRadius);
        clickMaxRadius = dp2px(clickMaxRadius);
        moveRadius = dp2px(moveRadius);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                clickPoint = new PointF(event.getX(), event.getY());
                movePoint = new PointF(event.getX(), event.getY());
                clickRadius = clickMaxRadius;
                break;
            case MotionEvent.ACTION_MOVE:
                movePoint.x = event.getX();
                movePoint.y = event.getY();
                break;
        }
        postInvalidate();
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (clickPoint == null || movePoint == null) return;
        refreshClickRadius();//重新设置圆的半径

        canvas.drawCircle(clickPoint.x, clickPoint.y, clickRadius, paint);//固定圆
        canvas.drawCircle(movePoint.x, movePoint.y, moveRadius, paint);//移动的圆
        Path bezierPath = drawBezierPath();
        if (bezierPath != null) {
            canvas.drawPath(bezierPath, paint);//画贝塞尔路径
        }
        super.onDraw(canvas);
    }

    private void refreshClickRadius() {
        double distance = Math.sqrt((clickPoint.x - movePoint.x) * (clickPoint.x - movePoint.x) + (clickPoint.y - movePoint.y) * (clickPoint.y - movePoint.y));
        clickRadius = (int) (clickMaxRadius - distance / 14);
    }


    private Path drawBezierPath() {
        if (clickRadius < clickMinRadius) return null;//超过最小限度不再画了
        Path path = new Path();
        //获取∠A的值
        double jiaoA = Math.atan(movePoint.y - clickPoint.y / movePoint.x - clickPoint.x);

        //贝塞尔曲线中心点
        float centerX = (movePoint.x + clickPoint.x) / 2;
        float centerY = (movePoint.y + clickPoint.y) / 2;

        //0点
        float p0x = (float) (clickPoint.x + clickRadius * Math.sin(jiaoA));
        float p0y = (float) (clickPoint.y - clickRadius * Math.cos(jiaoA));
        //1点
        float p1x = (float) (movePoint.x + moveRadius * Math.sin(jiaoA));
        float p1y = (float) (movePoint.y - moveRadius * Math.cos(jiaoA));
        //2点
        float p2x = (float) (movePoint.x - moveRadius * Math.sin(jiaoA));
        float p2y = (float) (movePoint.y + moveRadius * Math.cos(jiaoA));
        //3点
        float p3x = (float) (clickPoint.x - clickRadius * Math.sin(jiaoA));
        float p3y = (float) (clickPoint.y + clickRadius * Math.cos(jiaoA));
        //移动曲线
        path.moveTo(p0x, p0y);
        path.quadTo(centerX, centerY, p1x, p1y);
        path.lineTo(p2x, p2y);
        path.quadTo(centerX, centerY, p3x, p3y);
        return path;
    }

    private float dp2px(float dip) {
        return getResources().getDisplayMetrics().density * dip + 0.5f;
    }
}

我是加上引入包才1百来行代码的
接下来要按照一个图片进行分析了这里引入辉哥的图片
贝塞尔曲线图

主要思路就是在onTouchEvent中
ACTION_DOWN中刷新point的状态赋默认值
ACTION_MOVE中刷新移动点的坐标
之后就是在onDraw中
首先根据两个圆的位置获取圆心之间的间距根据间距画固定圆(固定圆的半径是根据间距确定的)
然后画移动的圆
最后根据path画我们的贝塞尔曲线代码不多大家根据花的图片理解下怎么画的有什么不明白的地方欢迎留言

猜你喜欢

转载自blog.csdn.net/u011048906/article/details/79413937
今日推荐