0
笛卡尔心形线绘制
A lonely cat 发表于 2020-07-29 18:55 135

笛卡尔心形线绘制

絮叨

“你相信童话吗?”、“你可以选择相信”—— 张东升

最近电影《隐秘的角落》热播,其中张东升给学生们讲了一个心形线的故事,不管它到底是不是真的,反正这个公式是真的。恰巧我刚找到了女票,嘿嘿。😁😁 于是乎,在View上绘制笛卡尔心形线的想法诞生了。😏😏

先上附上剧照里的原型图

图片描述

心形线极坐标方程

使用心形线极坐标方程绘制的效果图(没去实践,应该没问题)

图片描述

心形线的参数方程

看了下网上用极坐标方程绘制的效果图,感觉有点太圆润了,于是乎又找了另外的一个公式。

 

使用心形线参数方程绘制的效果图

图片描述

现在开始我们的表演


/**
 * @author A lonely cat
 * 心形视图
 */
public class HeartShapedView extends View {

    private static final String TAG = HeartShapedView.class.getSimpleName();
    private Paint mPaint;
    List<Float> xPositions = new ArrayList<>();
    List<Float> yPositions = new ArrayList<>();

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

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

    public HeartShapedView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initPaint();
    }

    private void initPaint() {
        //设置抗锯齿
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        //设置画笔的Style为填充
        mPaint.setStyle(Paint.Style.FILL);
        //设置画笔的颜色
        mPaint.setColor(Color.parseColor("#FF7996"));
        //设置画笔的宽度
        mPaint.setStrokeWidth(SizeUtils.dp2px(2));
    }

    /**
     * 计算路径
     */
    private void calc() {
        //缩放的程度,不建议太大
        int zoom = 20;
        for (int i = getWidth() / 4; i < getWidth() / 4 * 3; i++) {
            // x = 16 * (sin(t)) ^ 3;
            xPositions.add((float) (16 * Math.pow(Math.sin(i), 3)) * zoom);
            //此处如果不乘以 -1f ,将画出一个倒立的心形
            // y = 13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t)
            yPositions.add(-1f * (float) (13 * Math.cos(i) - 5 * Math.cos(2 * i) - 2 * Math.cos(3 * i) - Math.cos(4 * i)) * zoom);
        }
    }

    private boolean isFirstDraw = false;

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //只有第一次执行时才计算,避免多次计算,算是缓存坐标吧
        if (!isFirstDraw) {
            isFirstDraw = true;
            calc();
        }
        int width = getWidth();
        int height = getHeight();
        int radius;
        radius = width;
        int size = xPositions.size();
        for (int i = 0; i < size; i++) {
            canvas.save();
            Float x = xPositions.get(i);
            Float y = yPositions.get(i);
            //Log.d(TAG, "onDraw: =========x ===> " + x + "   y ====> " + y);
            //把当前画布的原点移到(x - width / 2, y - height / 2),后面的操作都以(x - width / 2, y - height / 2)作为参照原点,默认的原点坐标为(0, 0)
            canvas.translate(x - (width >> 1), y - (height >> 1));
            //绘制点
            canvas.drawPoint(radius, radius, mPaint);
            canvas.restore();
        }
    }
}

点个赞再走呗~

评论
0/240
  • 断点-含光君
    终于找到了女票,可以啊,骚,技术那些不重要了
    2020-07-29 21:18  回复
    1139423796017500160
  • 宿夜星辰叹
    无形秀恩爱,最为致命。
    2020-07-29 20:01  回复
    1256120724666454016
文章目录