Как правильно посчитать азимут для поворота карты?

У меня есть карта, которую мне необходимо повернуть. Делаю поворот я с помощью свойства bearing у Map. Мне не совсем понятно как правильно делать поворот относительно текущего положения карты, то есть азимут я считаю следующим разом

constexpr double constrain(double angle) {
    angle = std::fmod(angle, 360.);
    return angle < 0. ? angle + 360. : angle;
}

void GlobalMapProperty::setBearingByXY(const int &x, const int &y)
{
    const qreal bearing = Angular::constrain(std::atan2(y, x) * 180. / M_PI);

    setBearing(bearing);
}

Где функция setBearingByXY это свойство объекта, который задаётся в контекст. В функцию передаются координаты позиции мыши.

onPositionChanged: {
     if (pressedButtons == Qt.MidButton) {
                    console.log(mouseX, mouseY)
                    globalMapProperty.setBearingByXY(mouse.x, mouse.y)
                    _mouseArea.cursorShape = Qt.ClosedHandCursor
     }
}

Сейчас код отрабатывается и карта успешно поворачивается, но почему-то не совсем корректно. А именно если я нахожусь в Fullscreen режиме, то при зажатой СКМ по оси ординат или абцисс (если полностью проходить), то карта поворачивается на половину. Я почему-то думаю, что у меня где-то ошибка с вычислением азимута, то есть я не совсем верно его высчитываю. Может быть мне стоит его считать относительно центра экрана как-то?

Update: Как правильно передать координаты мыши, чтобы карта поворачивалась корректно. То есть при нахождении в верхней части экрана при зажатой СКМ, опускаясь вниз (нижняя часть экрана) азимут поворота был от 0 до 360, то есть полный поворот. Это первый уточняющий вопрос. Второй вопрос, если я повернул карту, и начну поворот заново, то поворот карты начинается заного, со стартовой позиции, предполагаю что это координата Qt.point(0, 0) для мапы.


Ответы (1 шт):

Автор решения: Albert Goldenshteyn

Азимут считался неверно! Нужно было во-первых: задать относительно чего производить вращение, во вторых начальную и финальные точки, где начальная точка - это точка нажатия мыши сигнал onPressed, а финальная точка - это точка текущего положения курсора onPositionChanged.

void GlobalMapProperty::setBearingByXY(const QPointF &start // точка старта,
                                       const QPointF &end // точка последнего положения мыши,
                                       const QPointF &origin // позиция, относительно которой производится вращение)
{
    qreal l;
    qreal x1 = start.x() - origin.x();
    qreal y1 = start.y() - origin.y();

    l = x1 * x1 + y1 * y1;

    if (!qFuzzyIsNull(l)) {
        x1 /= l;
        y1 /= l;
    }

    qreal x2 = end.x() - origin.x();
    qreal y2 = end.y() - origin.y();

    l = x2 * x2 + y2 * y2;

    if (!qFuzzyIsNull(l)) {
        x2 /= l;
        y2 /= l;
    }

    const qreal a1 = std::atan2(y1, x1);
    const qreal a2 = std::atan2(y2, x2);
    const qreal bearing = a2 - a1;

    setBearing(-bearing * 180. / M_PI);
}
→ Ссылка