Rotation Challenge


#1

Here is my solution for the rotation challenge. Is there a better way to do it?
Note that this will reset the rotation if the second finger is lifted and put again.

BoxDrawingView.java

@Override
	protected void onDraw(Canvas canvas){
		canvas.drawPaint(mBackgroundPaint);
		
		for(Box box : mBoxes){
			float left = Math.min(box.getOrigin().x, box.getCurrent().x);
			float right = Math.max(box.getOrigin().x, box.getCurrent().x);
			float top = Math.min(box.getOrigin().y, box.getCurrent().y);
			float bottom = Math.max(box.getOrigin().y, box.getCurrent().y);
			canvas.save();
			canvas.rotate(box.getRotationDegree(), box.getCurrent().x, box.getCurrent().y);
			canvas.drawRect(left, top, right, bottom, mBoxPaint);
			canvas.restore();
			
		}
	}
	
	public boolean onTouchEvent(MotionEvent event) {
		PointF curr0 = new PointF(event.getX(0), event.getY(0));;
		PointF curr1 = null;
		
		Log.i(TAG, "Box drawer at x=" + curr0.x + ", y=" + curr0.y + ":");
		
		switch (event.getActionMasked()) {
		case MotionEvent.ACTION_DOWN:
			Log.i(TAG, "  Action_Down");
			mCurrentBox = new Box(curr0);
			mBoxes.add(mCurrentBox);
			break;
		case MotionEvent.ACTION_POINTER_DOWN:
			if(mCurrentBox != null){
				curr1 = new PointF(event.getX(1), event.getY(1));
				mCurrentBox.setRotationOrigin(curr1);
				Log.i(TAG, "  Action_pointer_down second finger " + curr1.x + "," + curr1.y);
			}
			break;
		case MotionEvent.ACTION_MOVE:
			Log.i(TAG, "  Action_move");
			if(mCurrentBox != null){
				mCurrentBox.setCurrent(curr0);
				if(event.getPointerCount() > 1){
					Log.i(TAG, "  Action_move second finger");
					curr1 = new PointF(event.getX(1), event.getY(1));
					Log.i(TAG, "  Action_move second finger " + curr1.x + "," + curr1.y);
					mCurrentBox.setRotationCurrent(curr1);
				}
				invalidate();
			}
			break;
		case MotionEvent.ACTION_UP:
			Log.i(TAG, "  Action_up");
			mCurrentBox = null;
			break;
		case MotionEvent.ACTION_CANCEL:
			Log.i(TAG, "  Action_cancel");
			mCurrentBox = null;
			break;
		}
		
		return true;
	}

Box.java

public class Box {
	private final PointF mOrigin;
	private PointF mCurrent;
	private PointF mRotationOrigin;
	private PointF mRotationCurrent;

	public Box(PointF origin){
		mOrigin = mCurrent = mRotationCurrent = mRotationOrigin = origin;
	}
	
	public void setCurrent(PointF current){
		mCurrent = current;
	}
	
	public PointF getCurrent() {
		return mCurrent;
	}
	public PointF getOrigin() {
		return mOrigin;
	}

	public float getRotationDegree() {
		float slopeCurrent = 0;
		float slopeOrigin = 0;
		if(mCurrent.x - mRotationCurrent.x != 0)
			slopeCurrent = (mCurrent.y - mRotationCurrent.y)/(Math.abs(mCurrent.x - mRotationCurrent.x));
		if(mCurrent.x - mRotationOrigin.x != 0)
			slopeOrigin = (mCurrent.y - mRotationOrigin.y)/(Math.abs(mCurrent.x - mRotationOrigin.x));
		return (float)(Math.toDegrees(Math.atan(slopeCurrent) - Math.atan(slopeOrigin)));
	}

	public void setRotationOrigin(PointF rotationOrigin) {
		mRotationOrigin = mRotationCurrent = rotationOrigin;
	}

	public void setRotationCurrent(PointF rotationCurrent) {
		mRotationCurrent = rotationCurrent;
	}
}

#2

Another one method
dropbox.com/sh/aqsjuodqoew8 … Uzx9OUwGza