之前在手机上下了个输入数学函数就可以直接绘制出函数图形的app,发现里面必须要求解出y,才能绘制出图形,但是有些很复杂的函数不容易也根本不需要转换成f(x)的形式,比如 心形函数:
(17*(x^2))-(16*|x|*y)+(17*(y^2))<255 ; x(-5,5) y(-5,5)(心形函数式)
想看看这个函数的形状,但是本学渣根本不知道怎么解啊。。。还好我是个程序员,我可以自己画出来嘛。把方程看作一个判断然后绘制就行了。
下面是实现的代码:
1、首先在构造方法中创建一个自己的画板,paint和用来绘制心形的bitmap(这个bitmap是可变化的,canvas.drawxxx后bitmap会自动改变),用这种bitmap方式,是为了产生动画效果。然后开启一个线程,去判断函数式,描点绘制到我们的画板上。
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint();
mPaint.setColor(Color.RED);
mPaint.setAntiAlias(true);
mPaint.setStyle(Style.STROKE);
mPaint.setStrokeWidth(5f);
mBitmap = Bitmap.createBitmap(500,500, Bitmap.Config.ARGB_8888); //生成一个bitmap
mCanvas = new Canvas(mBitmap);
new Thread(){
@Override
public void run() {
super.run();
drawLove(mCanvas);
}
}.start();
}
2 绘制心形的核心方法:
判断思路是这样的,首先根据方程xy取值范围 把图形分为 4块(4个象限),2个for循环遍历一个象限的所有点,缩小实际坐标,得到方程范围的值,根据方程判断出符合的坐标,然后描点,下面判断了两个一个是y>0, 还一个是y<0,里面加250,是因为手机坐标原点是从左上角开始,所以原点平移到左上角,xy要加平移的距离
private void drawLove(Canvas canvas) {
//(17*(x^2))-(16*abs(x)*y)+(17*(y^2))<255 x(-5,5) y(-5,5) (心形函数方程式)
int loveWidth = 500;//心型宽度,必须是偶数
int oneLine = loveWidth/2;//一条轴长度
float scale = oneLine/5f;//实际坐标比上方程式坐标,倍数
for (int i = 0; i < oneLine; i++) {
for (int j = 0; j < oneLine; j++) {
//根据表达式xy的范围,所以要把坐标系的范围也缩小
float xf = i/scale;
float yf = j/scale;
if((17*Math.pow(xf, 2) - 16*Math.abs(xf)*yf+17*Math.pow(yf, 2))<255){
//右上1
// canvas.drawPoint(xf*scale+250,250+yf*scale, paint);
//左下2
canvas.drawPoint(250-xf*scale,250-yf*scale, mPaint);
// this.postInvalidateDelayed(10);
//右上1
// canvas.drawPoint(-xf*scale+250,250+yf*scale, paint);
//右下2
canvas.drawPoint(250+xf*scale,250-yf*scale, mPaint);
// this.postInvalidateDelayed(10);
// Log.i("TAG", "xf-->"+(xf*scale+250)+"yf-->"+(250-yf*scale));
}
if((17*Math.pow(xf, 2) - 16*Math.abs(xf)*(-yf)+17*Math.pow(yf, 2))<255){
//左上2
canvas.drawPoint(250-xf*scale, 250+yf*scale, mPaint);
//右下 1
// canvas.drawPoint(250+xf*scale,250-yf*scale, paint);
// this.postInvalidateDelayed(10);
//左上2
canvas.drawPoint(250+xf*scale, 250+yf*scale, mPaint);
//右下 1
// canvas.drawPoint(250-xf*scale,250-yf*scale, paint);
// this.postInvalidateDelayed(10);
}
//延时刷新,产生动画效果
delayedTime();
this.postInvalidate();
}
}//end for
}
3、重写onDraw(这个很简单,就一句话)
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(mBitmap, new Matrix(), mPaint);
}//end onDraw
private void delayedTime() {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
效果图:
Demo下载地址:点击打开链接