之前在手机上下了个输入数学函数就可以直接绘制出函数图形的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下载地址:点击打开链接