Почему 3 Vector2s/Points на прямой линии не имеют равных углов при разделении на 2 линии?

Как следует из названия, я пытаюсь дедуплицировать Vector2, которые появляются в одной строке.

Мой набор данных выглядит так:

(197, 59)
(197, 73)
(197, 76)

(Очевидно, все на одной вертикали)

Я искал найденное множество ответов, рассказывающих мне, как получить угол линии между двумя точками (после нормализации):

 float radians = Mathf.Acos(
                   Mathf.Clamp(
                     Vector2.Dot(from, to), 
                       -1f, 1f)));

Или

float dx = to.x - from.x;
float dy = to.y - from.y;
            
float radians = Math.Atan2(dy, dx) 

Или

   Vector2.Angle(from, to)

Или (я не уверен, что это правильно, но я не думаю, что код - это моя проблема)

float radians = MathF.Asin(Vector2.Dot(from, to) / from.magnitude+ to.magnitude);

Но я получаю другой ответ для A-> B, чем для B-> C .... Очевидно, я где-то что-то упускаю, но, как вы могли бы сказать, мои познания в математике ужасны. Может ли кто-нибудь указать мне в правильном направлении?

Вы можете увидеть результаты Vector2.Angle() на всем моем наборе данных ниже:

Getting angle of (197.00, 73.82)=>(197.00, 59.52). Normalised: (0.94, 0.35)=>(0.96, 0.29): Result 3.730666
Getting angle of (197.00, 76.62)=>(197.00, 73.82). Normalised: (0.93, 0.36)=>(0.94, 0.35): Result 0.7127182
Getting angle of (183.50, 140.60)=>(197.00, 116.29). Normalised: (0.79, 0.61)=>(0.86, 0.51): Result 6.904529
Getting angle of (197.00, 116.29)=>(197.00, 76.62). Normalised: (0.86, 0.51)=>(0.93, 0.36): Result 9.300751
Getting angle of (190.75, 158.58)=>(183.50, 140.60). Normalised: (0.77, 0.64)=>(0.79, 0.61): Result 2.279588
Getting angle of (197.00, 163.32)=>(190.75, 158.58). Normalised: (0.77, 0.64)=>(0.77, 0.64): Result 0.07661668
Getting angle of (197.00, 59.52)=>(197.00, 163.32). Normalised: (0.96, 0.29)=>(0.77, 0.64): Result 22.85009

Результат от Mathf.Atans (как указано выше) .... тот факт, что все результаты отличаются не только друг от друга, но и сверху, действительно показывает, насколько я застрял:

Getting angle of (197.00, 73.82)=>(197.00, 59.52). Normalised: (0.94, 0.35)=>(0.96, 0.29): Result -1.244842
Getting angle of (197.00, 76.62)=>(197.00, 73.82). Normalised: (0.93, 0.36)=>(0.94, 0.35): Result -1.206062
Getting angle of (183.50, 140.60)=>(197.00, 116.29). Normalised: (0.79, 0.61)=>(0.86, 0.51): Result -0.9772647
Getting angle of (197.00, 116.29)=>(197.00, 76.62). Normalised: (0.86, 0.51)=>(0.93, 0.36): Result -1.118683
Getting angle of (190.75, 158.58)=>(183.50, 140.60). Normalised: (0.77, 0.64)=>(0.79, 0.61): Result -0.8971169
Getting angle of (197.00, 163.32)=>(190.75, 158.58). Normalised: (0.77, 0.64)=>(0.77, 0.64): Result 2.263658
Getting angle of (197.00, 59.52)=>(197.00, 163.32). Normalised: (0.96, 0.29)=>(0.77, 0.64): Result 2.063599

Нормализация Atans без дает мне следующее. Прогресс!.... Я все еще ничего не понимаю и все равно был бы очень признателен хотя бы за ссылку на учебник, книгу, видео или что-то в этом роде! :D

Getting angle of (197.00, 73.82)=>(197.00, 59.52). Normalised: (197.00, 73.82)=>(197.00, 59.52): Result -1.570796
Getting angle of (197.00, 76.62)=>(197.00, 73.82). Normalised: (197.00, 76.62)=>(197.00, 73.82): Result -1.570796
Getting angle of (183.50, 140.60)=>(197.00, 116.29). Normalised: (183.50, 140.60)=>(197.00, 116.29): Result -1.063928
Getting angle of (197.00, 116.29)=>(197.00, 76.62). Normalised: (197.00, 116.29)=>(197.00, 76.62): Result -1.570796
Getting angle of (190.75, 158.58)=>(183.50, 140.60). Normalised: (190.75, 158.58)=>(183.50, 140.60): Result -1.953735
Getting angle of (197.00, 163.32)=>(190.75, 158.58). Normalised: (197.00, 163.32)=>(190.75, 158.58): Result -2.492572
Getting angle of (197.00, 59.52)=>(197.00, 163.32). Normalised: (197.00, 59.52)=>(197.00, 163.32): Result 1.570796

(Удаление нормализации из Vector2.Angle() дает те же результаты.... Почему?!)

У вас есть три точки или три вектора? Потому что скалярное произведение предназначено для векторов, и вы, кажется, идете по точкам. Atan2 должен дать тот же результат, если они находятся на одной строке, но, поскольку вы не показали, какие результаты вы получаете от них, трудно сказать.

Sami Kuhmonen 18.03.2022 20:22

Отредактировали. Когда я говорю «Вектор», я имею в виду «Вектор2», он же «Точка».

Graeme 18.03.2022 20:25

Что вы получаете за Math.Atan2 неправильное? Потому что для меня оба одинаковы для A-> B и B-> C, как и должно быть.

Sami Kuhmonen 18.03.2022 20:31

Я включил полную отладку из всего набора данных. Не все на одной линии, но большинство.

Graeme 18.03.2022 20:34

И добавил набор данных от Atans

Graeme 18.03.2022 20:40

Не существует такого понятия, как «угол» между двумя точками. Вы имели в виду рассчитать курс? Заголовок включает в себя второе направление, на котором основан заголовок, например, север или, может быть, Vector2.up в вашем случае. Кроме того, вы нормализуете позиции?

Ruzihm 18.03.2022 21:54

В Normalize позициях смысла мало! Это имеет смысл только для направления...

derHugo 18.03.2022 21:55

Вы нормализуете точки по какой-то причине. Это конечно все меняет. Не делайте этого и все работает.

Sami Kuhmonen 18.03.2022 22:02

Спасибо, все разумные комментарии. Я понял, что нормализация означает изменение точки, чтобы она имела четную длину. С вашими вопросами я понял, что точки не имеют длины. Но могу я спросить в ответ на то, что вы только что сказали... Чем вектор отличается от точки? Разве они не обертываются вокруг двух чисел?

Graeme 18.03.2022 22:16

@Грэм math.stackexchange.com/q/645672/611585

Ruzihm 18.03.2022 22:31

Спасибо Рузим! Это, безусловно, простое поле... Но только тогда, когда вы его уже знаете. Это очень помогает, так как дает мне язык, который мне нужен.

Graeme 18.03.2022 22:36

Просто добавим к ссылке @Ruzihm: позиция — это, по сути, вектор от начала мира 0,0,0 к вашей позиции. Если вы нормализуете это, вы получите новую позицию в том же направлении от источника, но ровно на 1 единицу от него. Поскольку ваши точки изначально находятся на прямой линии, после их нормализации они фактически будут размещены на краю круга с радиусом 1 вокруг начала мира, то есть по дуге. Вы можете себе представить, что таким образом угол, конечно, никогда не будет 0/180 ;)

derHugo 19.03.2022 06:57
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
12
39
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

«Вектор» может означать разные вещи в зависимости от контекста. В геометрическом контексте это обычно представляет либо точка, либо направление. Термин «вектор» иногда используется взаимозаменяемо с направлением, но я думаю, что полезно быть более конкретным.

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

var direction1 = myPoints[0] - myPoints[1];
var direction2 = myPoints[2] - myPoints[1];
 var angle = Vector2.Angle(direction1 , direction2 );

и вы должны получить угол для половины окружности.

Я бы сказал, что было бы понятнее использовать разные типы Point2 и Direction2, чтобы избежать путаницы или неправильного использования. И хотя некоторые векторные библиотеки используют этот подход, Unity3D — нет.

Спасибо за ответ - вы действительно помогаете мне понять. Могу я спросить, пример у вас показывает 3 балла. Можно ли получить угол направления относительно оси?

Graeme 18.03.2022 22:18

@Graeme Конечно, просто используйте направление в качестве одного параметра для функции угла и направление базовой оси в качестве другого.

JonasH 18.03.2022 22:21

Прошу прощения, здесь гугление меня не устраивает. Это будет 4 балла? Направление базовой оси будет, например, 0,0/0,1?

Graeme 18.03.2022 22:32

@Graeme направление базовой оси будет, например, (1, 0) для оси X и (0, 1) для оси Y. Но в принципе можно использовать любое направление. Обратите внимание, что нулевой вектор (0,0) является направлением нет, поскольку ему не хватает длины.

JonasH 18.03.2022 22:36

Черт возьми. Спасибо, что нашли время. Я ценю его.

Graeme 18.03.2022 22:37

Другие вопросы по теме