summaryrefslogtreecommitdiffstats
path: root/samples/browseable/AccelerometerPlay/src/com.example.android.accelerometerplay/AccelerometerPlayActivity.java
diff options
context:
space:
mode:
Diffstat (limited to 'samples/browseable/AccelerometerPlay/src/com.example.android.accelerometerplay/AccelerometerPlayActivity.java')
-rw-r--r--samples/browseable/AccelerometerPlay/src/com.example.android.accelerometerplay/AccelerometerPlayActivity.java429
1 files changed, 0 insertions, 429 deletions
diff --git a/samples/browseable/AccelerometerPlay/src/com.example.android.accelerometerplay/AccelerometerPlayActivity.java b/samples/browseable/AccelerometerPlay/src/com.example.android.accelerometerplay/AccelerometerPlayActivity.java
deleted file mode 100644
index b15685261..000000000
--- a/samples/browseable/AccelerometerPlay/src/com.example.android.accelerometerplay/AccelerometerPlayActivity.java
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- * 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.annotation.TargetApi;
-import android.app.Activity;
-import android.content.Context;
-import android.graphics.Bitmap;
-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.Build;
-import android.os.Bundle;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.view.Display;
-import android.view.Surface;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.FrameLayout;
-
-/**
- * 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);
- mSimulationView.setBackgroundResource(R.drawable.wood);
- 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 FrameLayout implements SensorEventListener {
- // diameter of the balls in meters
- private static final float sBallDiameter = 0.004f;
- private static final float sBallDiameter2 = sBallDiameter * sBallDiameter;
-
- private final int mDstWidth;
- private final int mDstHeight;
-
- private Sensor mAccelerometer;
- private long mLastT;
-
- private float mXDpi;
- private float mYDpi;
- private float mMetersToPixelsX;
- private float mMetersToPixelsY;
- private float mXOrigin;
- private float mYOrigin;
- private float mSensorX;
- private float mSensorY;
- private float mHorizontalBound;
- private float mVerticalBound;
- private final ParticleSystem mParticleSystem;
- /*
- * Each of our particle holds its previous and current position, its
- * acceleration. for added realism each particle has its own friction
- * coefficient.
- */
- class Particle extends View {
- private float mPosX = (float) Math.random();
- private float mPosY = (float) Math.random();
- private float mVelX;
- private float mVelY;
-
- public Particle(Context context) {
- super(context);
- }
-
- public Particle(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public Particle(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- public Particle(Context context, AttributeSet attrs, int defStyleAttr,
- int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- }
-
- public void computePhysics(float sx, float sy, float dT) {
-
- final float ax = -sx/5;
- final float ay = -sy/5;
-
- mPosX += mVelX * dT + ax * dT * dT / 2;
- mPosY += mVelY * dT + ay * dT * dT / 2;
-
- mVelX += ax * dT;
- mVelY += ay * dT;
- }
-
- /*
- * 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;
- mVelX = 0;
- } else if (x < -xmax) {
- mPosX = -xmax;
- mVelX = 0;
- }
- if (y > ymax) {
- mPosY = ymax;
- mVelY = 0;
- } else if (y < -ymax) {
- mPosY = -ymax;
- mVelY = 0;
- }
- }
- }
-
- /*
- * A particle system is just a collection of particles
- */
- class ParticleSystem {
- static final int NUM_PARTICLES = 5;
- 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(getContext());
- mBalls[i].setBackgroundResource(R.drawable.ball);
- mBalls[i].setLayerType(LAYER_TYPE_HARDWARE, null);
- addView(mBalls[i], new ViewGroup.LayoutParams(mDstWidth, mDstHeight));
- }
- }
-
- /*
- * 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) / 1000.f /** (1.0f / 1000000000.0f)*/;
- final int count = mBalls.length;
- for (int i = 0; i < count; i++) {
- Particle ball = mBalls[i];
- ball.computePhysics(sx, sy, 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;
- final float effectX = dx * c;
- final float effectY = dy * c;
- curr.mPosX -= effectX;
- curr.mPosY -= effectY;
- ball.mPosX += effectX;
- ball.mPosY += effectY;
- more = true;
- }
- }
- curr.resolveCollisionWithBounds();
- }
- }
- }
-
- public int getParticleCount() {
- return mBalls.length;
- }
-
- public float getPosX(int i) {
- return mBalls[i].mPosX;
- }
-
- public float getPosY(int i) {
- return mBalls[i].mPosY;
- }
- }
-
- public void startSimulation() {
- /*
- * It is not necessary to get accelerometer events at a very high
- * rate, by using a slower rate (SENSOR_DELAY_UI), we get an
- * automatic low-pass filter, which "extracts" the gravity component
- * of the acceleration. As an added benefit, we use less power and
- * CPU resources.
- */
- mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
- }
-
- public void stopSimulation() {
- mSensorManager.unregisterListener(this);
- }
-
- public SimulationView(Context context) {
- super(context);
- mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
-
- DisplayMetrics metrics = new DisplayMetrics();
- getWindowManager().getDefaultDisplay().getMetrics(metrics);
- mXDpi = metrics.xdpi;
- mYDpi = metrics.ydpi;
- mMetersToPixelsX = mXDpi / 0.0254f;
- mMetersToPixelsY = mYDpi / 0.0254f;
-
- // rescale the ball so it's about 0.5 cm on screen
- mDstWidth = (int) (sBallDiameter * mMetersToPixelsX + 0.5f);
- mDstHeight = (int) (sBallDiameter * mMetersToPixelsY + 0.5f);
- mParticleSystem = new ParticleSystem();
-
- Options opts = new Options();
- opts.inDither = true;
- opts.inPreferredConfig = Bitmap.Config.RGB_565;
- }
-
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- // compute the origin of the screen relative to the origin of
- // the bitmap
- mXOrigin = (w - mDstWidth) * 0.5f;
- mYOrigin = (h - mDstHeight) * 0.5f;
- mHorizontalBound = ((w / mMetersToPixelsX - sBallDiameter) * 0.5f);
- mVerticalBound = ((h / mMetersToPixelsY - sBallDiameter) * 0.5f);
- }
-
- @Override
- public void onSensorChanged(SensorEvent event) {
- if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
- return;
- /*
- * record the accelerometer data, the event's timestamp as well as
- * the current time. The latter is needed so we can calculate the
- * "present" time during rendering. In this application, we need to
- * take into account how the screen is rotated with respect to the
- * sensors (which always return data in a coordinate space aligned
- * to with the screen in its native orientation).
- */
-
- switch (mDisplay.getRotation()) {
- case Surface.ROTATION_0:
- mSensorX = event.values[0];
- mSensorY = event.values[1];
- break;
- case Surface.ROTATION_90:
- mSensorX = -event.values[1];
- mSensorY = event.values[0];
- break;
- case Surface.ROTATION_180:
- mSensorX = -event.values[0];
- mSensorY = -event.values[1];
- break;
- case Surface.ROTATION_270:
- mSensorX = event.values[1];
- mSensorY = -event.values[0];
- break;
- }
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- /*
- * Compute the new position of our object, based on accelerometer
- * data and present time.
- */
- final ParticleSystem particleSystem = mParticleSystem;
- final long now = System.currentTimeMillis();
- final float sx = mSensorX;
- final float sy = mSensorY;
-
- particleSystem.update(sx, sy, now);
-
- final float xc = mXOrigin;
- final float yc = mYOrigin;
- final float xs = mMetersToPixelsX;
- final float ys = mMetersToPixelsY;
- final int count = particleSystem.getParticleCount();
- for (int i = 0; i < count; i++) {
- /*
- * We transform the canvas so that the coordinate system matches
- * the sensors coordinate system with the origin in the center
- * of the screen and the unit is the meter.
- */
- final float x = xc + particleSystem.getPosX(i) * xs;
- final float y = yc - particleSystem.getPosY(i) * ys;
- particleSystem.mBalls[i].setTranslationX(x);
- particleSystem.mBalls[i].setTranslationY(y);
- }
-
- // and make sure to redraw asap
- invalidate();
- }
-
- @Override
- public void onAccuracyChanged(Sensor sensor, int accuracy) {
- }
- }
-}