三阶贝塞尔曲线绘制一个近似的圆方案

详见:http://spencermortensen.com/articles/bezier-circle/

近似值:c = 0.551915024494f

坐标系参考图:
这里写图片描述

结果:
这里写图片描述

package com.louisgeek.louiscustomviewstudy;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by louisgeek on 2016/10/28.
 */

public class BezierCurveViewDrawCircle extends View {

    /**
     * 控制点和半径的比例 详见:http://spencermortensen.com/articles/bezier-circle/
     */
    private final float C = 0.551915024494f;

    private  Paint mPaint;
    private  int mWidth,mHeight;

    private float mDisance;//控制点离数据点的距离

    //顺时针
    private  PointF[] mPointF_Data;
    private  PointF[] mPointF_Control;
    boolean drawControl=true;

    float mRadius=150f;

    public BezierCurveViewDrawCircle(Context context) {
        this(context, null);
    }
    public BezierCurveViewDrawCircle(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }
    public BezierCurveViewDrawCircle(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

         init();
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(4f);
        mPaint.setStyle(Paint.Style.STROKE);

        //
        mDisance=mRadius*C;

        /**
         * init
         */
        mPointF_Data=new PointF[2*4];
        for (int i = 0; i < mPointF_Data.length; i++) {
            mPointF_Data[i]=new PointF();
        }
        mPointF_Control=new PointF[2*4];
        for (int i = 0; i < mPointF_Control.length; i++) {
            mPointF_Control[i]=new PointF();
        }
        //图解 https://code.aliyun.com/hi31588535/outside_chain/raw/master/jiangjietu.png
        //屏幕坐标系的第一象限
        mPointF_Data[0].set(mRadius,0);//点P3
        mPointF_Data[1].set(0,mRadius);//点P0
        //屏幕坐标系的第二象限
        mPointF_Data[2].set(0,mRadius);//点P0
        mPointF_Data[3].set(-mRadius,0);//点P9
        //屏幕坐标系的第三象限
        mPointF_Data[4].set(-mRadius,0);//点P9
        mPointF_Data[5].set(0,-mRadius);//点P6
        //屏幕坐标系的第四象限
        mPointF_Data[6].set(0,-mRadius);//点P6
        mPointF_Data[7].set(mRadius,0);//点P3

        //屏幕坐标系的第一象限
        mPointF_Control[0].set(mRadius,mDisance);//点P2
        mPointF_Control[1].set(mDisance,mRadius);//点P1
        //屏幕坐标系的第二象限
        mPointF_Control[2].set(-mDisance,mRadius);//点P11
        mPointF_Control[3].set(-mRadius,mDisance);//点P10
        //屏幕坐标系的第三象限
        mPointF_Control[4].set(-mRadius,-mDisance);//点P8
        mPointF_Control[5].set(-mDisance,-mRadius);//点P7
        //屏幕坐标系的第四象限
        mPointF_Control[6].set(mDisance,-mRadius);//点P5
        mPointF_Control[7].set(mRadius,-mDisance);//点P4


    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mWidth=getMeasuredWidth();
        mHeight=getMeasuredHeight();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.translate(mWidth/2,mHeight/2);



        Path path=new Path();
        //屏幕坐标系的第1象限
        path.moveTo(mPointF_Data[0].x,mPointF_Data[0].y);
        path.cubicTo(mPointF_Control[0].x,mPointF_Control[0].y,mPointF_Control[1].x,mPointF_Control[1].y,mPointF_Data[1].x,mPointF_Data[1].y);

        //屏幕坐标系的第2象限
        path.moveTo(mPointF_Data[2].x,mPointF_Data[2].y);
        path.cubicTo(mPointF_Control[2].x,mPointF_Control[2].y,mPointF_Control[3].x,mPointF_Control[3].y,mPointF_Data[3].x,mPointF_Data[3].y);

        //屏幕坐标系的第3象限
        path.moveTo(mPointF_Data[4].x,mPointF_Data[4].y);
        path.cubicTo(mPointF_Control[4].x,mPointF_Control[4].y,mPointF_Control[5].x,mPointF_Control[5].y,mPointF_Data[5].x,mPointF_Data[5].y);

        //屏幕坐标系的第4象限
        path.moveTo(mPointF_Data[6].x,mPointF_Data[6].y);
        path.cubicTo(mPointF_Control[6].x,mPointF_Control[6].y,mPointF_Control[7].x,mPointF_Control[7].y,mPointF_Data[7].x,mPointF_Data[7].y);


        canvas.drawPath(path,mPaint);

        if (drawControl){
            drawControlLine(canvas);
        }
    }

    private void drawControlLine(Canvas canvas) {
        mPaint.setColor(Color.GRAY);
        canvas.drawLine(mPointF_Data[0].x,mPointF_Data[0].y,mPointF_Control[0].x,mPointF_Control[0].y,mPaint);
        mPaint.setColor(Color.YELLOW);
        canvas.drawLine(mPointF_Data[1].x,mPointF_Data[1].y,mPointF_Control[1].x,mPointF_Control[1].y,mPaint);
        mPaint.setColor(Color.LTGRAY);
        canvas.drawLine(mPointF_Data[2].x,mPointF_Data[2].y,mPointF_Control[2].x,mPointF_Control[2].y,mPaint);
        mPaint.setColor(Color.parseColor("#5DFED0"));
        canvas.drawLine(mPointF_Data[3].x,mPointF_Data[3].y,mPointF_Control[3].x,mPointF_Control[3].y,mPaint);
        mPaint.setColor(Color.BLACK);
        canvas.drawLine(mPointF_Data[4].x,mPointF_Data[4].y,mPointF_Control[4].x,mPointF_Control[4].y,mPaint);
        mPaint.setColor(Color.BLUE);
        canvas.drawLine(mPointF_Data[5].x,mPointF_Data[5].y,mPointF_Control[5].x,mPointF_Control[5].y,mPaint);
        mPaint.setColor(Color.GREEN);
        canvas.drawLine(mPointF_Data[6].x,mPointF_Data[6].y,mPointF_Control[6].x,mPointF_Control[6].y,mPaint);
        mPaint.setColor(Color.parseColor("#FE6EEB"));
        canvas.drawLine(mPointF_Data[7].x,mPointF_Data[7].y,mPointF_Control[7].x,mPointF_Control[7].y,mPaint);

    }


}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值