/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */package com.example.android.accelerometerplay;import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.BitmapFactory.Options;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.View;
import android.view.WindowManager;/**
 * This is an example of using the accelerometer to integrate the device's
 * acceleration to a position using the Verlet method. This is illustrated with
 * a very simple particle system comprised of a few iron balls freely moving on
 * an inclined wooden table. The inclination of the virtual table is controlled
 * by the device's accelerometer.
 * 
 * @see SensorManager
 * @see SensorEvent
 * @see Sensor
 */public class AccelerometerPlayActivity extends Activity {    private SimulationView mSimulationView;
    private SensorManager mSensorManager;
    private PowerManager mPowerManager;
    private WindowManager mWindowManager;
    private Display mDisplay;
    private WakeLock mWakeLock;    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);        // Get an instance of the SensorManager
        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);        // Get an instance of the PowerManager
        mPowerManager = (PowerManager) getSystemService(POWER_SERVICE);        // Get an instance of the WindowManager
        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        mDisplay = mWindowManager.getDefaultDisplay();        // Create a bright wake lock
        mWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, getClass()
                .getName());        // instantiate our simulation view and set it as the activity's content
        mSimulationView = new SimulationView(this);
        setContentView(mSimulationView);
    }    @Override
    protected void onResume() {
        super.onResume();
        /*
         * when the activity is resumed, we acquire a wake-lock so that the
         * screen stays on, since the user will likely not be fiddling with the
         * screen or buttons.
         */
        mWakeLock.acquire();        // Start the simulation
        mSimulationView.startSimulation();
    }    @Override
    protected void onPause() {
        super.onPause();
        /*
         * When the activity is paused, we make sure to stop the simulation,
         * release our sensor resources and wake locks
         */        // Stop the simulation
        mSimulationView.stopSimulation();        // and release our wake-lock
        mWakeLock.release();
    }    class SimulationView extends View implements SensorEventListener {
        // diameter of the balls in meters
        private static final float sBallDiameter = 0.009f;
        private static final float sBallDiameter2 = sBallDiameter * sBallDiameter;        // friction of the virtual table and air
        private static final float sFriction = 0.1f;        private Sensor mAccelerometer;
        private long mLastT;
        private float mLastDeltaT;        private float mXDpi;
        private float mYDpi;
        private float mMetersToPixelsX;
        private float mMetersToPixelsY;
        private Bitmap mBitmap;
        private Bitmap mWood;
        private float mXOrigin;
        private float mYOrigin;
        private float mSensorX;
        private float mSensorY;
        private long mSensorTimeStamp;
        private long mCpuTimeStamp;
        private float mHorizontalBound;
        private float mVerticalBound;
        private float widthFullSrceen;
        private float heighFullSrceen;
        private final ParticleSystem mParticleSystem = new ParticleSystem();

解决方案 »

  1.   

        /*
             * Each of our particle holds its previous and current position, its
             * acceleration. for added realism each particle has its own friction
             * coefficient.
             */
            class Particle {
                private float mPosX;
                private float mPosY;
                private float mAccelX;
                private float mAccelY;
                private float mLastPosX;
                private float mLastPosY;
                private float mOneMinusFriction;
               
                Particle() {
                    // make each particle a bit different by randomizing its
                    // coefficient of friction
                    final float r = ((float) Math.random() - 0.5f) * 0.2f;
                    mOneMinusFriction = 1.0f - sFriction + r;
                }            public void computePhysics(float sx, float sy, float dT, float dTC) {
                    // Force of gravity applied to our virtual object
                    final float m = 1000.0f; // mass of our virtual object
                    final float gx = -sx * m;
                    final float gy = -sy * m;                /*
                     * 稦 = mA <=> A = 稦 / m We could simplify the code by
                     * completely eliminating "m" (the mass) from all the equations,
                     * but it would hide the concepts from this sample code.
                     */
                    final float invm = 1.0f / m;
                    final float ax = gx * invm;
                    final float ay = gy * invm;                /*
                     * Time-corrected Verlet integration The position Verlet
                     * integrator is defined as x(t+苩) = x(t) + x(t) - x(t-苩) +
                     * a(t)苩�2 However, the above equation doesn't handle variable
                     * 苩 very well, a time-corrected version is needed: x(t+苩) =
                     * x(t) + (x(t) - x(t-苩)) * (苩/苩_prev) + a(t)苩�2 We also add
                     * a simple friction term (f) to the equation: x(t+苩) = x(t) +
                     * (1-f) * (x(t) - x(t-苩)) * (苩/苩_prev) + a(t)苩�2
                     */
                    final float dTdT = dT * dT;
                    final float x = mPosX + mOneMinusFriction * dTC * (mPosX - mLastPosX) + mAccelX
                            * dTdT;
                    final float y = mPosY + mOneMinusFriction * dTC * (mPosY - mLastPosY) + mAccelY
                            * dTdT;
                    mLastPosX = mPosX;
                    mLastPosY = mPosY;
                    mPosX = x;
                    mPosY = y;
                    mAccelX = ax;
                    mAccelY = ay;
                }            /*
                 * Resolving constraints and collisions with the Verlet integrator
                 * can be very simple, we simply need to move a colliding or
                 * constrained particle in such way that the constraint is
                 * satisfied.
                 */
                public void resolveCollisionWithBounds() {
                    final float xmax = mHorizontalBound;
                    final float ymax = mVerticalBound;
                    final float x = mPosX;
                    final float y = mPosY;
                    if (x > xmax) {
                        mPosX = xmax;
                    } else if (x < -xmax) {
                        mPosX = -xmax;
                    }
                    if (y > ymax) {
                        mPosY = ymax;
                    } else if (y < -ymax) {
                        mPosY = -ymax;
                    }
                }
                
      

  2.   

              
                // Liu Ke add this function 
                public void resolveSubFrameBounds()
                {
                 final float mx = mPosX;
                    final float my = mPosY;
                  
                    final float xc = mXOrigin;
                    final float yc = mYOrigin;
                    final float xs = mMetersToPixelsX;
                    final float ys = mMetersToPixelsY;
                    
                    final float xl = xc + mx * xs;
                    final float xr = xc - mx * xs;                
                    final float y = yc - my * ys;
                    
                    DisplayMetrics metrics = new DisplayMetrics();
                    getWindowManager().getDefaultDisplay().getMetrics(metrics);
                  
                 
                   
                    
                    
               //    float sBallDiameter = xc+0.00045f*xs;
                   float widthFullSrceen = metrics.widthPixels;
              
                   final int balltWidth = (int) (sBallDiameter * xs + 0.5f);
            //       final int balltHeight = (int) (sBallDiameter * mMetersToPixelsY + 0.5f);
                    
                    float line1x =  (widthFullSrceen/3)*1;   
                    float line2x =  (widthFullSrceen/3)*2;
                   // Log.i("x position",String.valueOf(x));
               //     Log.i(ALARM_SERVICE, String.valueOf(x));
               //     Log.i("y position",String.valueOf(y));    
                    //设置边框高度
                    
                    if(y<275)
                    {            
                    
                     if(xl>0&&xl<line1x)
                     {
                     if(Math.abs(xl-line1x)<20)
                     {
                     // mPosX = mLastPosX;
                     //Log.i("x right position",String.valueOf(xr));
                     //Log.i("x left position",String.valueOf(xl));
                     //Log.i("line 1",String.valueOf(line1x));
                     }
                     }
                     else if (xl >line1x && xl <line2x)
                     {
                     //if (Math.abs(xl-line1x)<20)
                     //mPosX = mLastPosX;
                     }
                     else if (xl >line2x)
                     {
                     /*
                     if (Math.abs(xl-line2x)<20)
                     {
                     Log.i("x left position",String.valueOf(xl));
                     Log.i("line 1",String.valueOf(line2x));
                     Log.i("mlastpox",String.valueOf(mLastPosX));
                     mPosX = mLastPosX;
                     }
                     */
                     //if(Math.abs( Math.abs (xl-(balltWidth/2)-line2x)<0.5)
                    
                    
                     //if(Math.abs (xl-(balltWidth/2) -line2x)<0.5)
                     // if    ( ( xl -74 - line2x )<1 && ( xl -74 - line2x )>0)
                     //{
                     Log.i("xc",String.valueOf(xc));
                     Log.i("球的半径",String.valueOf(balltWidth/2));
                     Log.i("x left position",String.valueOf(xl));
                     Log.i("x right position",String.valueOf(xr));
                     Log.i("line 2",String.valueOf(line2x));
                     Log.i("全屏幕款",String.valueOf(widthFullSrceen));
                     mPosX = mLastPosX;
                     // }
                    
                     }
                    }
                
                }
            }        /*
             * A particle system is just a collection of particles
             */
            class ParticleSystem {
                static final int NUM_PARTICLES = 1;
                private Particle mBalls[] = new Particle[NUM_PARTICLES];            ParticleSystem() {
                    /*
                     * Initially our particles have no speed or acceleration
                     */
                    for (int i = 0; i < mBalls.length; i++) {
                        mBalls[i] = new Particle();
                    }
                }            /*
                 * Update the position of each particle in the system using the
                 * Verlet integrator.
                 */
                private void updatePositions(float sx, float sy, long timestamp) {
                    final long t = timestamp;
                    if (mLastT != 0) {
                        final float dT = (float) (t - mLastT) * (1.0f / 1000000000.0f);
                        if (mLastDeltaT != 0) {
                            final float dTC = dT / mLastDeltaT;
                            final int count = mBalls.length;
                            for (int i = 0; i < count; i++) {
                                Particle ball = mBalls[i];
                                ball.computePhysics(sx, sy, dT, dTC);
                            }
                        }
                        mLastDeltaT = dT;
                    }
                    mLastT = t;
                }            /*
                 * Performs one iteration of the simulation. First updating the
                 * position of all the particles and resolving the constraints and
                 * collisions.
                 */
                public void update(float sx, float sy, long now) {
                    // update the system's positions
                    updatePositions(sx, sy, now);                // We do no more than a limited number of iterations
                    final int NUM_MAX_ITERATIONS = 10;                /*
                     * Resolve collisions, each particle is tested against every
                     * other particle for collision. If a collision is detected the
                     * particle is moved away using a virtual spring of infinite
                     * stiffness.
                     */
                    boolean more = true;
                    final int count = mBalls.length;
                    for (int k = 0; k < NUM_MAX_ITERATIONS && more; k++) {
                        more = false;
                        
                        for (int i = 0; i < count; i++) {
                            Particle curr = mBalls[i];
                            for (int j = i + 1; j < count; j++) {
                                Particle ball = mBalls[j];
                                float dx = ball.mPosX - curr.mPosX;
                                float dy = ball.mPosY - curr.mPosY;
                                float dd = dx * dx + dy * dy;
                                // Check for collisions
                                if (dd <= sBallDiameter2) {
                                    /*
                                     * add a little bit of entropy, after nothing is
                                     * perfect in the universe.
                                     */
                                    dx += ((float) Math.random() - 0.5f) * 0.0001f;
                                    dy += ((float) Math.random() - 0.5f) * 0.0001f;
                                    dd = dx * dx + dy * dy;
                                    // simulate the spring
                                    final float d = (float) Math.sqrt(dd);
                                    final float c = (0.5f * (sBallDiameter - d)) / d;
                                    curr.mPosX -= dx * c;
                                    curr.mPosY -= dy * c;
                                    ball.mPosX += dx * c;
                                    ball.mPosY += dy * c;
                                    more = true;
                                }
                            }
                            /*
                             * Finally make sure the particle doesn't intersects
                             * with the walls.
                             */
                            curr.resolveCollisionWithBounds();
                            
                            //控制球进框子
                            curr.resolveSubFrameBounds();
                            
                        }
                    }
                }            public int getParticleCount() {
                    return mBalls.length;
                }            public float getPosX(int i) {
                    return mBalls[i].mPosX;
                }            public float getPosY(int i) {
                    return mBalls[i].mPosY;
                }
            }