142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen/*
242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen * Copyright (C) 2009 The Android Open Source Project
342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen *
442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen * Licensed under the Apache License, Version 2.0 (the "License");
542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen * you may not use this file except in compliance with the License.
642dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen * You may obtain a copy of the License at
742dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen *
842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen *      http://www.apache.org/licenses/LICENSE-2.0
942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen *
1042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen * Unless required by applicable law or agreed to in writing, software
1142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen * distributed under the License is distributed on an "AS IS" BASIS,
1242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen * See the License for the specific language governing permissions and
1442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen * limitations under the License.
1542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen */
1642dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
17b84cf9e1e378f6cc6642b4ac3f391a85b208a23bXavier Ducrohetpackage com.example.android.livecubes.cube1;
1842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
1942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissenimport android.graphics.Canvas;
2042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissenimport android.graphics.Paint;
2142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissenimport android.graphics.Rect;
2242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissenimport android.os.Handler;
2342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissenimport android.os.SystemClock;
2442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissenimport android.service.wallpaper.WallpaperService;
2542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissenimport android.util.Log;
2642dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissenimport android.view.MotionEvent;
2742dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissenimport android.view.SurfaceHolder;
2842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
2942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen/*
3042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen * This animated wallpaper draws a rotating wireframe cube.
3142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen */
3242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissenpublic class CubeWallpaper1 extends WallpaperService {
3342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
3442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen    private final Handler mHandler = new Handler();
3542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
3642dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen    @Override
3742dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen    public void onCreate() {
3842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        super.onCreate();
3942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen    }
4042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
4142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen    @Override
4242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen    public void onDestroy() {
4342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        super.onDestroy();
4442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen    }
4542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
4642dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen    @Override
4742dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen    public Engine onCreateEngine() {
4842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        return new CubeEngine();
4942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen    }
5042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
5142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen    class CubeEngine extends Engine {
5242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
5342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        private final Paint mPaint = new Paint();
5442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        private float mOffset;
5542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        private float mTouchX = -1;
5642dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        private float mTouchY = -1;
5742dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        private long mStartTime;
5842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        private float mCenterX;
5942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        private float mCenterY;
6042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
6142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        private final Runnable mDrawCube = new Runnable() {
6242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            public void run() {
6342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen                drawFrame();
6442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            }
6542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        };
6642dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        private boolean mVisible;
6742dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
6842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        CubeEngine() {
6942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            // Create a Paint to draw the lines for our cube
7042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            final Paint paint = mPaint;
7142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            paint.setColor(0xffffffff);
7242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            paint.setAntiAlias(true);
7342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            paint.setStrokeWidth(2);
7442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            paint.setStrokeCap(Paint.Cap.ROUND);
7542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            paint.setStyle(Paint.Style.STROKE);
7642dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
7742dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            mStartTime = SystemClock.elapsedRealtime();
7842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        }
7942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
8042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        @Override
8142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        public void onCreate(SurfaceHolder surfaceHolder) {
8242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            super.onCreate(surfaceHolder);
8342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
8442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            // By default we don't get touch events, so enable them.
8542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            setTouchEventsEnabled(true);
8642dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        }
8742dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
8842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        @Override
8942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        public void onDestroy() {
9042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            super.onDestroy();
9142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            mHandler.removeCallbacks(mDrawCube);
9242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        }
9342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
9442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        @Override
9542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        public void onVisibilityChanged(boolean visible) {
9642dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            mVisible = visible;
9742dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            if (visible) {
9842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen                drawFrame();
9942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            } else {
10042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen                mHandler.removeCallbacks(mDrawCube);
10142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            }
10242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        }
10342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
10442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        @Override
10542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
10642dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            super.onSurfaceChanged(holder, format, width, height);
10742dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            // store the center of the surface, so we can draw the cube in the right spot
10842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            mCenterX = width/2.0f;
10942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            mCenterY = height/2.0f;
11042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            drawFrame();
11142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        }
11242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
11342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        @Override
11442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        public void onSurfaceCreated(SurfaceHolder holder) {
11542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            super.onSurfaceCreated(holder);
11642dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        }
11742dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
11842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        @Override
11942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        public void onSurfaceDestroyed(SurfaceHolder holder) {
12042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            super.onSurfaceDestroyed(holder);
12142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            mVisible = false;
12242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            mHandler.removeCallbacks(mDrawCube);
12342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        }
12442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
12542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        @Override
12642c35199db9b3ec2ec467f926538e5d748e0b49dMarco Nelissen        public void onOffsetsChanged(float xOffset, float yOffset,
12742c35199db9b3ec2ec467f926538e5d748e0b49dMarco Nelissen                float xStep, float yStep, int xPixels, int yPixels) {
12842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            mOffset = xOffset;
12942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            drawFrame();
13042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        }
13142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
13242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        /*
13342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen         * Store the position of the touch event so we can use it for drawing later
13442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen         */
13542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        @Override
13642dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        public void onTouchEvent(MotionEvent event) {
13742dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            if (event.getAction() == MotionEvent.ACTION_MOVE) {
13842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen                mTouchX = event.getX();
13942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen                mTouchY = event.getY();
14042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            } else {
14142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen                mTouchX = -1;
14242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen                mTouchY = -1;
14342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            }
14442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            super.onTouchEvent(event);
14542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        }
14642dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
14742dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        /*
14842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen         * Draw one frame of the animation. This method gets called repeatedly
14942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen         * by posting a delayed Runnable. You can do any drawing you want in
15042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen         * here. This example draws a wireframe cube.
15142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen         */
15242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        void drawFrame() {
15342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            final SurfaceHolder holder = getSurfaceHolder();
15442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
15542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            Canvas c = null;
15642dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            try {
15742dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen                c = holder.lockCanvas();
15842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen                if (c != null) {
15942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen                    // draw something
16042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen                    drawCube(c);
16142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen                    drawTouchPoint(c);
16242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen                }
16342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            } finally {
16442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen                if (c != null) holder.unlockCanvasAndPost(c);
16542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            }
16642dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
16742dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            // Reschedule the next redraw
16842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            mHandler.removeCallbacks(mDrawCube);
16942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            if (mVisible) {
17042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen                mHandler.postDelayed(mDrawCube, 1000 / 25);
17142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            }
17242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        }
17342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
17442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        /*
17542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen         * Draw a wireframe cube by drawing 12 3 dimensional lines between
17642dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen         * adjacent corners of the cube
17742dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen         */
17842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        void drawCube(Canvas c) {
17942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            c.save();
18042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            c.translate(mCenterX, mCenterY);
18142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            c.drawColor(0xff000000);
18242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            drawLine(c, -400, -400, -400,  400, -400, -400);
18342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            drawLine(c,  400, -400, -400,  400,  400, -400);
18442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            drawLine(c,  400,  400, -400, -400,  400, -400);
18542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            drawLine(c, -400,  400, -400, -400, -400, -400);
18642dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
18742dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            drawLine(c, -400, -400,  400,  400, -400,  400);
18842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            drawLine(c,  400, -400,  400,  400,  400,  400);
18942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            drawLine(c,  400,  400,  400, -400,  400,  400);
19042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            drawLine(c, -400,  400,  400, -400, -400,  400);
19142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
19242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            drawLine(c, -400, -400,  400, -400, -400, -400);
19342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            drawLine(c,  400, -400,  400,  400, -400, -400);
19442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            drawLine(c,  400,  400,  400,  400,  400, -400);
19542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            drawLine(c, -400,  400,  400, -400,  400, -400);
19642dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            c.restore();
19742dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        }
19842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
19942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        /*
20042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen         * Draw a 3 dimensional line on to the screen
20142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen         */
20242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        void drawLine(Canvas c, int x1, int y1, int z1, int x2, int y2, int z2) {
20342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            long now = SystemClock.elapsedRealtime();
20442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            float xrot = ((float)(now - mStartTime)) / 1000;
20542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            float yrot = (0.5f - mOffset) * 2.0f;
20642dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            float zrot = 0;
20742dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
20842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            // 3D transformations
20942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
21042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            // rotation around X-axis
21142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            float newy1 = (float)(Math.sin(xrot) * z1 + Math.cos(xrot) * y1);
21242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            float newy2 = (float)(Math.sin(xrot) * z2 + Math.cos(xrot) * y2);
21342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            float newz1 = (float)(Math.cos(xrot) * z1 - Math.sin(xrot) * y1);
21442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            float newz2 = (float)(Math.cos(xrot) * z2 - Math.sin(xrot) * y2);
21542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
21642dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            // rotation around Y-axis
21742dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            float newx1 = (float)(Math.sin(yrot) * newz1 + Math.cos(yrot) * x1);
21842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            float newx2 = (float)(Math.sin(yrot) * newz2 + Math.cos(yrot) * x2);
21942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            newz1 = (float)(Math.cos(yrot) * newz1 - Math.sin(yrot) * x1);
22042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            newz2 = (float)(Math.cos(yrot) * newz2 - Math.sin(yrot) * x2);
22142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
22242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            // 3D-to-2D projection
22342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            float startX = newx1 / (4 - newz1 / 400);
22442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            float startY = newy1 / (4 - newz1 / 400);
22542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            float stopX =  newx2 / (4 - newz2 / 400);
22642dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            float stopY =  newy2 / (4 - newz2 / 400);
22742dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
22842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            c.drawLine(startX, startY, stopX, stopY, mPaint);
22942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        }
23042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
23142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        /*
23242dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen         * Draw a circle around the current touch point, if any.
23342dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen         */
23442dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        void drawTouchPoint(Canvas c) {
23542dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            if (mTouchX >=0 && mTouchY >= 0) {
23642dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen                c.drawCircle(mTouchX, mTouchY, 80, mPaint);
23742dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen            }
23842dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen        }
23942dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen
24042dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen    }
24142dbb8b92b8c5c63d82fd9e571557b900a5bad7bMarco Nelissen}
242