Как следует из названия, я пытаюсь дедуплицировать 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() дает те же результаты.... Почему?!)
Отредактировали. Когда я говорю «Вектор», я имею в виду «Вектор2», он же «Точка».
Что вы получаете за Math.Atan2
неправильное? Потому что для меня оба одинаковы для A-> B и B-> C, как и должно быть.
Я включил полную отладку из всего набора данных. Не все на одной линии, но большинство.
И добавил набор данных от Atans
Не существует такого понятия, как «угол» между двумя точками. Вы имели в виду рассчитать курс? Заголовок включает в себя второе направление, на котором основан заголовок, например, север или, может быть, Vector2.up
в вашем случае. Кроме того, вы нормализуете позиции?
В Normalize
позициях смысла мало! Это имеет смысл только для направления...
Вы нормализуете точки по какой-то причине. Это конечно все меняет. Не делайте этого и все работает.
Спасибо, все разумные комментарии. Я понял, что нормализация означает изменение точки, чтобы она имела четную длину. С вашими вопросами я понял, что точки не имеют длины. Но могу я спросить в ответ на то, что вы только что сказали... Чем вектор отличается от точки? Разве они не обертываются вокруг двух чисел?
@Грэм math.stackexchange.com/q/645672/611585
Спасибо Рузим! Это, безусловно, простое поле... Но только тогда, когда вы его уже знаете. Это очень помогает, так как дает мне язык, который мне нужен.
Просто добавим к ссылке @Ruzihm: позиция — это, по сути, вектор от начала мира 0,0,0
к вашей позиции. Если вы нормализуете это, вы получите новую позицию в том же направлении от источника, но ровно на 1 единицу от него. Поскольку ваши точки изначально находятся на прямой линии, после их нормализации они фактически будут размещены на краю круга с радиусом 1 вокруг начала мира, то есть по дуге. Вы можете себе представить, что таким образом угол, конечно, никогда не будет 0/180 ;)
«Вектор» может означать разные вещи в зависимости от контекста. В геометрическом контексте это обычно представляет либо точка, либо направление. Термин «вектор» иногда используется взаимозаменяемо с направлением, но я думаю, что полезно быть более конкретным.
При вычислении углов они должны представлять направления, поскольку брать угол двух точек бессмысленно. Поэтому вам нужно преобразовать точки в направления. Например, взяв направление от центральной точки к левой и правой точкам:
var direction1 = myPoints[0] - myPoints[1];
var direction2 = myPoints[2] - myPoints[1];
var angle = Vector2.Angle(direction1 , direction2 );
и вы должны получить угол для половины окружности.
Я бы сказал, что было бы понятнее использовать разные типы Point2
и Direction2
, чтобы избежать путаницы или неправильного использования. И хотя некоторые векторные библиотеки используют этот подход, Unity3D — нет.
Спасибо за ответ - вы действительно помогаете мне понять. Могу я спросить, пример у вас показывает 3 балла. Можно ли получить угол направления относительно оси?
@Graeme Конечно, просто используйте направление в качестве одного параметра для функции угла и направление базовой оси в качестве другого.
Прошу прощения, здесь гугление меня не устраивает. Это будет 4 балла? Направление базовой оси будет, например, 0,0/0,1?
@Graeme направление базовой оси будет, например, (1, 0) для оси X и (0, 1) для оси Y. Но в принципе можно использовать любое направление. Обратите внимание, что нулевой вектор (0,0) является направлением нет, поскольку ему не хватает длины.
Черт возьми. Спасибо, что нашли время. Я ценю его.
У вас есть три точки или три вектора? Потому что скалярное произведение предназначено для векторов, и вы, кажется, идете по точкам. Atan2 должен дать тот же результат, если они находятся на одной строке, но, поскольку вы не показали, какие результаты вы получаете от них, трудно сказать.