Я пытаюсь найти 2D-вектор в наборе, который ближе всего к указанному углу от другого вектора.
Так что если у меня есть v(10, 10)
и я хотел бы найти ближайший другой вектор под углом 90 градусов, он должен найти v(20, 10)
, например. Я написал метод, который, я думаю, возвращает правильную ориентацию между двумя векторами.
float getBearing(
const sf::Vector2f& a, const sf::Vector2f& b)
{
float degs = atan2f(b.y - a.y, b.x - a.x) * (180 / M_PI);
return (degs > 0.0f ? degs : (360.0f + degs)) + 90.0f;
}
Это, кажется, работает хорошо, хотя, если я помещу один над другим, он возвращает 180, что хорошо, и 360, что просто странно. Разве он не должен возвращать 0, если он прямо над ним? Лучший способ сделать это — проверить 360 и вернуть 0, я думаю.
Моя проблема в том, что я не могу определить разницу между пройденным углом, например, 90 градусов, и углом, возвращенным из getBearing
, Я даже не уверен, верен ли подшипник во всех ситуациях.
Может ли кто-нибудь помочь исправить какие-то явно очевидные ошибки в моем методе подшипников и предложить способ получить разницу между двумя подшипниками? Я охотился через Интернет, но есть так много способов сделать это, большинство из которых показаны на других языках.
Благодарю.
Я бы предложил взять два вектора, которые сравниваются, и сделать произведение на единицу. Ближайший ориентир должен быть наибольшим, 1 — максимум (означает, что векторы указывают в одном и том же направлении), а -1 — минимум (означает, что векторы указывают в противоположных направлениях).
Если вам нужно просто найти векторы, ближайшие к определенному углу, вы можете воспользоваться методом @swtdrgn; если вместо этого вам нужно вычислить разность углов между двумя векторами, вы можете воспользоваться простым свойством точечного произведения:
где тета — угол между двумя векторами; Таким образом, перевернув формулу, вы получите:
Я нашел решение на данный момент. Я потратил немало часов, пытаясь решить эту проблему, и, наконец, я делаю это через несколько минут после того, как спросил ТАК, типично. Возможно, есть гораздо лучший способ сделать это, поэтому я по-прежнему открыт для предложений из других ответов.
Я все еще использую свой метод пеленга из вопроса в данный момент, который всегда будет возвращать значение между 0 и 360. Затем я получаю разницу между возвращенным значением и указанным углом, как это было.
fabs(fmodf(getBearing(vectorA, vectorB) + 180 - angle, 360) - 180);
Это вернет положительное смещение, которое измеряет расстояние в градусах между подшипником между двумя векторами. @ swtdrgn ответ предлагает использовать скалярное произведение двух векторов, это может быть намного проще, чем мой метод пеленга, потому что мне на самом деле не нужен угол, мне просто нужна разница.