Рассчитайте угол точки касания и поверните его в Android - PullRequest
8 голосов
/ 28 октября 2011

Матем снова победил меня.Это такая простая задача, но мне не удается ее выполнить.

Сценарий: я рисую на SurfaceView круглое изображение.Пользователь касается точки на границе изображения и начинает ее перетаскивать.Мне нужно повернуть изображение круга в соответствии с движением пользователя.У меня есть два важных элемента информации: координаты X, Y и координаты точек касания.

enter image description here

Как видно на изображении, пользователь коснулся точки,в соответствии с моей ничьей угол касания должен быть около 40. Я не могу рассчитать его правильно.

Я пытался использовать эту формулу:

angle = Math.atan2(touchedY - centerY, touchedX - centerX) * 180 / Math.PI 

Мне не удаетсяпонять, как я должен рассчитывать угол, как сейчас, он не работает должным образом и значения не являются хорошими.Например, в случае изображения угол вычисления составляет -50.

Спасибо за ваше время, любая информация с радостью принимается.

Л.Е .: На самом деле, я думаю, что я допустил ошибку, как указано ниже.Если круг будет иметь вид:

enter image description here

Ответы [ 6 ]

11 голосов
/ 28 октября 2011

Давайте переформулируем проблему: вы хотите найти угол между двумя векторами.Первый вектор - это восходящий вектор, идущий прямо от вашей центральной точки ( u ), а второй вектор - это вектор от центральной точки к точке касания ( v ).

Теперь мы можем вспомнить (или Google), что

cos a = uv / (| u | * | v |)

Где a - угол между векторами и | u |длина вектора.Верхний вектор, u , равен (0, 1) и имеет длину 1.

Умножение векторов вручную отменяет x-член и дает нам что-то вроде этого.

double tx = touch_x - center_x, ty = touch_y - center_y;
double t_length = Math.sqrt(tx*tx + ty*ty);
double a = Math.acos(ty / t_length);

Обратите внимание, как вектор v получается путем вычитания центральной точки из точки касания.Не забудьте конвертировать в градусы, если это необходимо.

5 голосов
/ 28 октября 2011

Прежде всего, угол поворота должен определяться происхождением CenterX и CenterY.Таким образом, ваш (коснулся Y - центр Y, коснулся X - центр X) должен быть (центр Y - коснулся Y, центр X - коснулся X).

И правильный ответ может быть:

(int) (Math.toDegrees(Math.atan2(centerY - touchedY, centerX - touchedX)));

Надеюсь, это поможет

1 голос
/ 23 мая 2017
private fun getAngle(touchX: Float, touchY: Float): Double {
    var angle: Double
    val x2 = touchX - centerX
    val y2 = touchY - centerY
    val d1 = Math.sqrt((centerY * centerY).toDouble())
    val d2 = Math.sqrt((x2 * x2 + y2 * y2).toDouble())
    if (touchX >= centerX) {
        angle = Math.toDegrees(Math.acos((-centerY * y2) / (d1 * d2)))
    } else
        angle = 360 - Math.toDegrees(Math.acos((-centerY * y2) / (d1 * d2)))
    return angle
}

, где touchX = event.getX и touchY = event.getY

1 голос
/ 13 февраля 2014

Я много чего пытался сделать что-то подобное и получил следующее:

Получается позиция просмотра вместо центра экрана, но вы можете добавить ее:

ОБРАТНЫЙ ВИД ИЗОБРАЖЕНИЯ НА ОСНОВЕ ТОЧКИ ТОЧКИ:

     iv = (ImageView) findViewById(R.id.soldier); // img view to rotate
     int touch_x = (int) event.getX(); // touch point x
     int touch_y = (int) event.getY(); // touch point y
     int[] location = new int[2];
     iv.getLocationInWindow(location);   // get img location on screen

       float angle = (float) Math.toDegrees(Math.atan2( touch_x - location[0],    touch_y -   location[1]));

        if(angle < 0){
            angle += 360;
        }


     iv.setRotation(-angle);
1 голос
/ 28 октября 2011

Вам нужно 3 точки на угол.У вас есть только 2 (центр и сенсорный).Выберите фиксированную третью точку, например, точку 90 на вашей картинке, и используйте ответ @ vidstige, чтобы найти уравнение.

0 голосов
/ 26 января 2019

это для угла между двумя точками в градусах

angle = (Math.atan2(y2-y1,x2-x1) *180 / Math.PI)

...