1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.example.android.apis.graphics; 18 19 import com.example.android.apis.R; 20 21 import android.content.Context; 22 import android.graphics.*; 23 import android.os.Bundle; 24 import android.view.*; 25 import android.util.FloatMath; 26 27 public class BitmapMesh extends GraphicsActivity { 28 29 @Override onCreate(Bundle savedInstanceState)30 protected void onCreate(Bundle savedInstanceState) { 31 super.onCreate(savedInstanceState); 32 setContentView(new SampleView(this)); 33 } 34 35 private static class SampleView extends View { 36 private static final int WIDTH = 20; 37 private static final int HEIGHT = 20; 38 private static final int COUNT = (WIDTH + 1) * (HEIGHT + 1); 39 40 private final Bitmap mBitmap; 41 private final float[] mVerts = new float[COUNT*2]; 42 private final float[] mOrig = new float[COUNT*2]; 43 44 private final Matrix mMatrix = new Matrix(); 45 private final Matrix mInverse = new Matrix(); 46 setXY(float[] array, int index, float x, float y)47 private static void setXY(float[] array, int index, float x, float y) { 48 array[index*2 + 0] = x; 49 array[index*2 + 1] = y; 50 } 51 SampleView(Context context)52 public SampleView(Context context) { 53 super(context); 54 setFocusable(true); 55 56 mBitmap = BitmapFactory.decodeResource(getResources(), 57 R.drawable.beach); 58 59 float w = mBitmap.getWidth(); 60 float h = mBitmap.getHeight(); 61 // construct our mesh 62 int index = 0; 63 for (int y = 0; y <= HEIGHT; y++) { 64 float fy = h * y / HEIGHT; 65 for (int x = 0; x <= WIDTH; x++) { 66 float fx = w * x / WIDTH; 67 setXY(mVerts, index, fx, fy); 68 setXY(mOrig, index, fx, fy); 69 index += 1; 70 } 71 } 72 73 mMatrix.setTranslate(10, 10); 74 mMatrix.invert(mInverse); 75 } 76 onDraw(Canvas canvas)77 @Override protected void onDraw(Canvas canvas) { 78 canvas.drawColor(0xFFCCCCCC); 79 80 canvas.concat(mMatrix); 81 canvas.drawBitmapMesh(mBitmap, WIDTH, HEIGHT, mVerts, 0, 82 null, 0, null); 83 } 84 warp(float cx, float cy)85 private void warp(float cx, float cy) { 86 final float K = 10000; 87 float[] src = mOrig; 88 float[] dst = mVerts; 89 for (int i = 0; i < COUNT*2; i += 2) { 90 float x = src[i+0]; 91 float y = src[i+1]; 92 float dx = cx - x; 93 float dy = cy - y; 94 float dd = dx*dx + dy*dy; 95 float d = FloatMath.sqrt(dd); 96 float pull = K / (dd + 0.000001f); 97 98 pull /= (d + 0.000001f); 99 // android.util.Log.d("skia", "index " + i + " dist=" + d + " pull=" + pull); 100 101 if (pull >= 1) { 102 dst[i+0] = cx; 103 dst[i+1] = cy; 104 } else { 105 dst[i+0] = x + dx * pull; 106 dst[i+1] = y + dy * pull; 107 } 108 } 109 } 110 111 private int mLastWarpX = -9999; // don't match a touch coordinate 112 private int mLastWarpY; 113 onTouchEvent(MotionEvent event)114 @Override public boolean onTouchEvent(MotionEvent event) { 115 float[] pt = { event.getX(), event.getY() }; 116 mInverse.mapPoints(pt); 117 118 int x = (int)pt[0]; 119 int y = (int)pt[1]; 120 if (mLastWarpX != x || mLastWarpY != y) { 121 mLastWarpX = x; 122 mLastWarpY = y; 123 warp(pt[0], pt[1]); 124 invalidate(); 125 } 126 return true; 127 } 128 } 129 } 130 131