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 26 public class BitmapMesh extends GraphicsActivity { 27 28 @Override onCreate(Bundle savedInstanceState)29 protected void onCreate(Bundle savedInstanceState) { 30 super.onCreate(savedInstanceState); 31 setContentView(new SampleView(this)); 32 } 33 34 private static class SampleView extends View { 35 private static final int WIDTH = 20; 36 private static final int HEIGHT = 20; 37 private static final int COUNT = (WIDTH + 1) * (HEIGHT + 1); 38 39 private final Bitmap mBitmap; 40 private final float[] mVerts = new float[COUNT*2]; 41 private final float[] mOrig = new float[COUNT*2]; 42 43 private final Matrix mMatrix = new Matrix(); 44 private final Matrix mInverse = new Matrix(); 45 setXY(float[] array, int index, float x, float y)46 private static void setXY(float[] array, int index, float x, float y) { 47 array[index*2 + 0] = x; 48 array[index*2 + 1] = y; 49 } 50 SampleView(Context context)51 public SampleView(Context context) { 52 super(context); 53 setFocusable(true); 54 55 mBitmap = BitmapFactory.decodeResource(getResources(), 56 R.drawable.beach); 57 58 float w = mBitmap.getWidth(); 59 float h = mBitmap.getHeight(); 60 // construct our mesh 61 int index = 0; 62 for (int y = 0; y <= HEIGHT; y++) { 63 float fy = h * y / HEIGHT; 64 for (int x = 0; x <= WIDTH; x++) { 65 float fx = w * x / WIDTH; 66 setXY(mVerts, index, fx, fy); 67 setXY(mOrig, index, fx, fy); 68 index += 1; 69 } 70 } 71 72 mMatrix.setTranslate(10, 10); 73 mMatrix.invert(mInverse); 74 } 75 onDraw(Canvas canvas)76 @Override protected void onDraw(Canvas canvas) { 77 canvas.drawColor(0xFFCCCCCC); 78 79 canvas.concat(mMatrix); 80 canvas.drawBitmapMesh(mBitmap, WIDTH, HEIGHT, mVerts, 0, 81 null, 0, null); 82 } 83 warp(float cx, float cy)84 private void warp(float cx, float cy) { 85 final float K = 10000; 86 float[] src = mOrig; 87 float[] dst = mVerts; 88 for (int i = 0; i < COUNT*2; i += 2) { 89 float x = src[i+0]; 90 float y = src[i+1]; 91 float dx = cx - x; 92 float dy = cy - y; 93 float dd = dx*dx + dy*dy; 94 float d = (float) Math.sqrt(dd); 95 float pull = K / (dd + 0.000001f); 96 97 pull /= (d + 0.000001f); 98 // android.util.Log.d("skia", "index " + i + " dist=" + d + " pull=" + pull); 99 100 if (pull >= 1) { 101 dst[i+0] = cx; 102 dst[i+1] = cy; 103 } else { 104 dst[i+0] = x + dx * pull; 105 dst[i+1] = y + dy * pull; 106 } 107 } 108 } 109 110 private int mLastWarpX = -9999; // don't match a touch coordinate 111 private int mLastWarpY; 112 onTouchEvent(MotionEvent event)113 @Override public boolean onTouchEvent(MotionEvent event) { 114 float[] pt = { event.getX(), event.getY() }; 115 mInverse.mapPoints(pt); 116 117 int x = (int)pt[0]; 118 int y = (int)pt[1]; 119 if (mLastWarpX != x || mLastWarpY != y) { 120 mLastWarpX = x; 121 mLastWarpY = y; 122 warp(pt[0], pt[1]); 123 invalidate(); 124 } 125 return true; 126 } 127 } 128 } 129 130