将位图旋转到运动方向
Rotate bitmap to movement direction
我正在尝试根据我的运动事件的运动方向旋转位图图像,假设我有一张汽车的俯视图图像,我希望汽车朝向我的运动方向,如果我向左移动它应该旋转 180 度,向上它应该变成 90 度等等,请原谅我的英语不好,iv 只设法按照 0 为中心旋转图像
//this is how i rotate
double ComputeAngle(float x, float y){
final double RADS_TO_DEGREES = 360 / (Math.PI * 2);
double result = Math.atan2(y,x) * RADS_TO_DEGREES;
if (result < 0){
result = 360 + result;
}
return result;
}
//bitmap to rotate pretend its a car from top view
Bitmap bitmap;
//draws bitmap
private final RectF tmpRF = new RectF();
final void drawStrokePoint(Canvas c, float x, float y, float r) {
tmpRF.set(x-r,y-r,x+r,y+r);
//compute rotation
float rotation = (float)ComputeAngle(x, y);
Matrix matrix = new Matrix();
matrix.postTranslate(-bitmap.getWidth()/2, -bitmap.getHeight()/2);
matrix.postRotate(rotation);
matrix.postTranslate(x, y);
//draw bitmap
c.drawBitmap(mAirbrushBits, matrix, null);
}
//get x y cords and draw at x y position
@Override
public boolean onTouchEvent(MotionEvent event)
{
float x = event.getX();
float y = event.getY();
switch (event.getAction() & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
strokeX = x;
strokeY = y;
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_MOVE:
drawStrokePoint(drawCanvas, x, y, currentWidth);
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
}
return true;
}
在您的方法 ComputeAngle 中,您没有计算正确的移动角度。为此,您还需要 x 和 y 的旧值。该方法如下所示:
double ComputeAngle(double x, double y, double oldX, double oldY){
// calculates the direction vector
double directionX = x - oldX;
double directionY = y - oldY;
double vectorLength = Math.sqrt(directionX * directionX + directionY * directionY);
// normalize the direction vector (coordinate / |v|)
double normalizedX = directionX / vectorLength;
double normalizedY = directionY / vectorLength;
//Obtains the angle relative to the vector over the axis X (1,0)
// The formula is the angle = scalar(v1, v2)/|v1||v2|
double angleRadians = (normalizedX) / Math.sqrt(normalizedX*normalizedX + normalizedY*normalizedY);
// This formula will give you a angle between 0 and 180, to obtain the other half you must check the direction
if (directionY < 0)
angleRadians += Math.PI;
return angleRadians * RADS_TO_DEGREES;
}
我正在尝试根据我的运动事件的运动方向旋转位图图像,假设我有一张汽车的俯视图图像,我希望汽车朝向我的运动方向,如果我向左移动它应该旋转 180 度,向上它应该变成 90 度等等,请原谅我的英语不好,iv 只设法按照 0 为中心旋转图像
//this is how i rotate
double ComputeAngle(float x, float y){
final double RADS_TO_DEGREES = 360 / (Math.PI * 2);
double result = Math.atan2(y,x) * RADS_TO_DEGREES;
if (result < 0){
result = 360 + result;
}
return result;
}
//bitmap to rotate pretend its a car from top view
Bitmap bitmap;
//draws bitmap
private final RectF tmpRF = new RectF();
final void drawStrokePoint(Canvas c, float x, float y, float r) {
tmpRF.set(x-r,y-r,x+r,y+r);
//compute rotation
float rotation = (float)ComputeAngle(x, y);
Matrix matrix = new Matrix();
matrix.postTranslate(-bitmap.getWidth()/2, -bitmap.getHeight()/2);
matrix.postRotate(rotation);
matrix.postTranslate(x, y);
//draw bitmap
c.drawBitmap(mAirbrushBits, matrix, null);
}
//get x y cords and draw at x y position
@Override
public boolean onTouchEvent(MotionEvent event)
{
float x = event.getX();
float y = event.getY();
switch (event.getAction() & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
strokeX = x;
strokeY = y;
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_MOVE:
drawStrokePoint(drawCanvas, x, y, currentWidth);
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
}
return true;
}
在您的方法 ComputeAngle 中,您没有计算正确的移动角度。为此,您还需要 x 和 y 的旧值。该方法如下所示:
double ComputeAngle(double x, double y, double oldX, double oldY){
// calculates the direction vector
double directionX = x - oldX;
double directionY = y - oldY;
double vectorLength = Math.sqrt(directionX * directionX + directionY * directionY);
// normalize the direction vector (coordinate / |v|)
double normalizedX = directionX / vectorLength;
double normalizedY = directionY / vectorLength;
//Obtains the angle relative to the vector over the axis X (1,0)
// The formula is the angle = scalar(v1, v2)/|v1||v2|
double angleRadians = (normalizedX) / Math.sqrt(normalizedX*normalizedX + normalizedY*normalizedY);
// This formula will give you a angle between 0 and 180, to obtain the other half you must check the direction
if (directionY < 0)
angleRadians += Math.PI;
return angleRadians * RADS_TO_DEGREES;
}