笛卡尔心形线绘制
絮叨
“你相信童话吗?”、“你可以选择相信”—— 张东升
最近电影《隐秘的角落》热播,其中张东升给学生们讲了一个心形线的故事,不管它到底是不是真的,反正这个公式是真的。恰巧我刚找到了女票,嘿嘿。?? 于是乎,在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();
}
}
}
点个赞再走呗~
本文由
A lonely cat
原创发布于
阳光沙滩
,未经作者授权,禁止转载