gpt4 book ai didi

Android:如何通过触摸旋转元素?

转载 作者:太空宇宙 更新时间:2023-11-03 13:38:09 25 4
gpt4 key购买 nike

我试图通过触摸并移动手指来旋转 View 内的可绘制对象。我提出了几种解决方案,但没有一种在设备上感觉自然。

这是我的第一种方法:根据用户触摸屏幕的位置和手指移动的方向,我正在更改可绘制对象的旋转,或多或少是任意计算的。

private void updateRotation(float x, float y, float oldX, float oldY) {
int width = getWidth();
int height = getHeight();

float centerX = width / 2;
float centerY = height / 2;

float xSpeed = rotationSpeed(x, oldX, width);
float ySpeed = rotationSpeed(y, oldY, height);

if ((y < centerY && x > oldX)
|| (y > centerY && x < oldX))
rotation += xSpeed;
else if ((y < centerY && x < oldX)
|| (y > centerY && x > oldX))
rotation -= xSpeed;

if ((x > centerX && y > oldY)
|| (x < centerX && y < oldY))
rotation += ySpeed;
else if ((x > centerX && y < oldY)
|| (x < centerX && y > oldY))
rotation -= ySpeed;
}

private static float rotationSpeed(float pos, float oldPos, float max) {
return (Math.abs(pos - oldPos) * 180) / max;
}

这种方法有一些恼人的副作用:有时手指不动时 drawable 会旋转,而且旋转速度通常不如用户手指快。

因此我放弃了这段代码并开始使用我的第二种方法。我正在使用三角函数来计算相当于手指移动的实际旋转:

private void updateRotation(float x, float y, float oldX, float oldY) {
float centerX = getWidth() / 2;
float centerY = getHeight() / 2;

float a = distance(centerX, centerY, x, y);
float b = distance(centerX, centerY, oldX, oldY);
float c = distance(x, y, oldX, oldY);

double r = Math.acos((Math.pow(a, 2) + Math.pow(b, 2) - Math.pow(c, 2))
/ (2 * a * b));

if ((oldY < centerY && x < oldX)
|| (oldY > centerY && x > oldX)
|| (oldX > centerX && y < oldY)
|| (oldX < centerX && y > oldY))
r *= -1;

rotation += (int) Math.toDegrees(r);
}

private float distance(float x1, float y1, float x2, float y2) {
return Math.abs(x1 - x2) + Math.abs(y1 - y2);
}

虽然这对我来说听起来确实是正确的解决方案,但它也不是很好用。手指运动有时会被忽略——计算成本会不会太高?此外,旋转仍然比实际手指移动快一点。

理想情况下,如果我开始旋转触摸特定点的可绘制对象,则该点应始终保持在手指下方。你能告诉我如何实现这一目标吗?

编辑:

我采纳了 Snailer 的建议。我必须将 atan2 方法的参数切换到正确的方向,现在效果很好:

private void updateRotation(float x, float y) {
double r = Math.atan2(x - getWidth() / 2, getHeight() / 2 - y);
rotation = (int) Math.toDegrees(r);
}

最佳答案

这可以通过获取手指与屏幕中心形成的角度轻松完成。类似于上面第二个示例中的内容。在您的 onTouchEvent 中将 getX()/getY() 发送到此方法:

    private double getDegreesFromTouchEvent(float x, float y){
double delta_x = x - (Screen Width) /2;
double delta_y = (Screen Height) /2 - y;
double radians = Math.atan2(delta_y, delta_x);

return Math.toDegrees(radians);
}

然后当你 draw() 时,你可以根据结果旋转 Canvas。显然,您需要使用 if (MotionEvent.getAction() == MotionEvent.ACTION_MOVE) 来更新角度。

关于Android:如何通过触摸旋转元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4179456/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com