Как определить n-мерный вектор вращения и отражения в haskell?
Как определить вращение и отражение вектора в целом, где функция будет работать в n измерениях в Haskell?
В настоящее время у меня есть скалярное произведение, нормализация и проекция, но я застрял на отражении и повороте.
data Vector s a = Vector {len::s,arr::a}
normalize :: Vector s a → Vector s a
normalize = toVector . uncurry (zipWith (/))
. (id&&&(repeat . sqrt . sum . map (^2)))
. fromVector
dot :: Vector s a → Vector s a → a
dot v = sum ∘ zipWith (*) (fromVector v) ∘ fromVector
project :: Vector s a → Vector s a → Vector s a
project v = toVector ∘ uncurry (zipWith (*))
∘ (fromVector&&&(repeat ∘ (v`dot`)))
Я искал несколько дней, но кажется, что использование Haskell для понимания математики может иногда вызывать проблемы, когда нет четкого кода (или вообще нет кода), и единственные учебники по n-мерным векторам проходят мимо моих знаний по математике.
2 ответа
Что касается математических аспектов n-мерных вращений, я мог бы порекомендовать публикации Эндрю Дж. Хансона из Отделения компьютерных наук Университета Индианы. Особенно:
"Вращения для N-мерной компьютерной графики" https://www.cs.indiana.edu/pub/techreports/TR406.pdf
Этот документ является преемником "Геометрии для N-мерной компьютерной графики" https://classes.soe.ucsc.edu/cmps161/Winter14/papers/pv/ggndgeom.pdf
Математика требует знания векторной арифметики и линейной алгебры, но если вы собираетесь выполнять N-мерные преобразования, это рекомендуемый способ сделать математику.
Математика должна помочь нам пройти большую часть пути сюда; вращение в n-мерном пространстве можно рассматривать как преобразование, основанное на n-2-мерном объекте (т.е. точке на плоскости или линии в 3-мерном пространстве. Аналогично, отражение можно рассматривать как преобразование основанный вокруг n-1 мерного объекта.
У вас будут проблемы с попыткой определить повороты для чего-то меньшего, чем трехмерный вектор, и отражения для чего-либо меньшего, чем двухмерный вектор. Общий подход может заключаться в определении функции двух параметров; один для вектора, который вы вращаете, и одно "осевое" представление (точка для двумерного вектора).
Поскольку длина вектора (и объекта, который он трансформирует) важна для определения того, имеет ли смысл поворот или отражение, это будет хорошим вариантом использования для зависимой типизации (вы можете указать относительную длину векторов в типе подписи). К сожалению, Haskell пока не поддерживает это в полной мере (хотя некоторые экспериментальные языки, такие как Idris, поддерживают), поэтому ваши варианты составляют:
- Реализуйте отражения и повороты как частичные функции, которые перестают работать, если размеры векторов неправильны,
- Реализовать еще одну более общую функцию для преобразований вокруг любой меньшей размерной "оси" (на самом деле не уверен, возможно ли это),
- Попробуйте использовать язык с зависимыми типами (если вам нужны гарантии безопасности типов, или
- Проявите творческий подход с вашими реализациями
Я бы сказал, что в большинстве случаев академическая родословная Хаскелла делает ее полезной для исследовательской математики, но она еще не идеальна.