Android - 如何旋转图像
Android - How to spin the image
我有一张图片,它在 imageView 中。我想添加一个功能,允许用户在尝试将图像旋转到右侧时旋转图像 side.For 例如,如果用户尝试将图像旋转到左侧,它不会旋转。
这是我的转轮。
我尝试使用 GestureDetector 和 onFling 事件,但它不足以检测用户是否试图将其旋转到右侧或左侧。我该怎么做?
编辑:
var normalVectorX = e2?.x!! - 515
var normalVectorY = e2?.y!! - 515
var tangentVectorX = -normalVectorY
var tangentVectorY = normalVectorX
var tangentVectorLength = (Math.sqrt(Math.pow((515 - e2?.y!!).toDouble(), 2.0)) + Math.pow((e2?.x!! - 515).toDouble(), 2.0))
var unitTangentX = tangentVectorX / tangentVectorLength
var unitTangentY = tangentVectorY / tangentVectorLength
var scalarProjection = (velocityX * unitTangentX) + (velocityY * unitTangentY)
if (scalarProjection > 0) // Right Side
spinWheel((spinCountX * 360).toFloat() + 360 - (mPrizeIndex * 60) , 12000)
这是基于answer伪代码的代码实现。
515 = 轮子的中心。
onFling
为您提供相应投掷手势的 MotionEvent
。然后您可以调用 getX(int)
和 getY(int)
来获取坐标。
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
float x = e2.getX(0); // Assuming you only care about the first finger
float y = e2.getY(0);
if (x < imageView.getWidth() / 2) {
// fling is on the left side
} else {
// fling is on the right side
}
}
旁注:我认为如果水平滑动,上面的代码会表现得不自然。如果你想让你的旋转手势更逼真,我认为你最好计算 tangential component.
编辑:这是计算切向分量的方法。
您需要计算触摸事件所在点圆的单位切线上的速度矢量 scalar projection。
伪代码:
velocityVector = (velocityX, velocityY)
locationOfTouch = (e2.getX(0), e2.getY(0))
centerOfWheel = (166, 155) # Measured from your image
normalVector = locationOfTouch - centerOfWheel
= (locationOfTouch.x - centerOfWheel.x, locationOfTouch.y - centerOfWheel.y)
为了获得顺时针方向的切向量,我们采用 normalVector,交换 X 和 Y 分量,并对 X 取反(来自 2D Euclidean vector rotations)。
tangentVector = (-normalVector.y, normalVector.x)
unitTangent = tangentVector / tangentVector.length()
最后,你取点积得到标量投影:
scalarProjection = velocityVector.dotProduct(unitTangent)
= (velocityVector.x * unitTangent.x) + (velocityVector.y * unitTangent.y)
如果scalarProjection
为正数,表示滑动手势为顺时针方向。如果为负数,则表示手势为逆时针方向。
作为奖励,由于我们使用了单位切线,因此生成的标量投影也代表顺时针方向的投掷速度,因此您可以将旋转动画更改得更快或更慢,或者设置一个阈值,例如那个方向的小速度不会触发轮子旋转。
我有一张图片,它在 imageView 中。我想添加一个功能,允许用户在尝试将图像旋转到右侧时旋转图像 side.For 例如,如果用户尝试将图像旋转到左侧,它不会旋转。
这是我的转轮。
我尝试使用 GestureDetector 和 onFling 事件,但它不足以检测用户是否试图将其旋转到右侧或左侧。我该怎么做?
编辑:
var normalVectorX = e2?.x!! - 515
var normalVectorY = e2?.y!! - 515
var tangentVectorX = -normalVectorY
var tangentVectorY = normalVectorX
var tangentVectorLength = (Math.sqrt(Math.pow((515 - e2?.y!!).toDouble(), 2.0)) + Math.pow((e2?.x!! - 515).toDouble(), 2.0))
var unitTangentX = tangentVectorX / tangentVectorLength
var unitTangentY = tangentVectorY / tangentVectorLength
var scalarProjection = (velocityX * unitTangentX) + (velocityY * unitTangentY)
if (scalarProjection > 0) // Right Side
spinWheel((spinCountX * 360).toFloat() + 360 - (mPrizeIndex * 60) , 12000)
这是基于answer伪代码的代码实现。 515 = 轮子的中心。
onFling
为您提供相应投掷手势的 MotionEvent
。然后您可以调用 getX(int)
和 getY(int)
来获取坐标。
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
float x = e2.getX(0); // Assuming you only care about the first finger
float y = e2.getY(0);
if (x < imageView.getWidth() / 2) {
// fling is on the left side
} else {
// fling is on the right side
}
}
旁注:我认为如果水平滑动,上面的代码会表现得不自然。如果你想让你的旋转手势更逼真,我认为你最好计算 tangential component.
编辑:这是计算切向分量的方法。
您需要计算触摸事件所在点圆的单位切线上的速度矢量 scalar projection。
伪代码:
velocityVector = (velocityX, velocityY)
locationOfTouch = (e2.getX(0), e2.getY(0))
centerOfWheel = (166, 155) # Measured from your image
normalVector = locationOfTouch - centerOfWheel
= (locationOfTouch.x - centerOfWheel.x, locationOfTouch.y - centerOfWheel.y)
为了获得顺时针方向的切向量,我们采用 normalVector,交换 X 和 Y 分量,并对 X 取反(来自 2D Euclidean vector rotations)。
tangentVector = (-normalVector.y, normalVector.x)
unitTangent = tangentVector / tangentVector.length()
最后,你取点积得到标量投影:
scalarProjection = velocityVector.dotProduct(unitTangent)
= (velocityVector.x * unitTangent.x) + (velocityVector.y * unitTangent.y)
如果scalarProjection
为正数,表示滑动手势为顺时针方向。如果为负数,则表示手势为逆时针方向。
作为奖励,由于我们使用了单位切线,因此生成的标量投影也代表顺时针方向的投掷速度,因此您可以将旋转动画更改得更快或更慢,或者设置一个阈值,例如那个方向的小速度不会触发轮子旋转。