2

通常如何定义矢量旋转和反射,函数在 Haskell 中的n维中工作?

目前我已经完成了点积、归一化和投影,但停留在反射和旋转上。

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 维向量的唯一教程超出了我的数学知识。

4

2 回答 2

1

关于 n 维旋转的数学方面,我可能会推荐印第安纳大学计算机科学系的 Andrew J. Hanson 的出版物。尤其是:

“N 维计算机图形的旋转” https://www.cs.indiana.edu/pub/techreports/TR406.pdf

该论文是“N 维计算机图形学的几何”的继任者 https://classes.soe.ucsc.edu/cmps161/Winter14/papers/pv/ggndgeom.pdf

数学需要矢量算术和线性代数的知识,但如果您要执行 N 维变换,这是推荐的数学方法。

于 2017-06-28T01:01:12.923 回答
-1

数学应该能够让我们了解大部分情况;n 维空间中的旋转可以被认为是基于 n-2 维对象(即平面上的点,或 3 空间中的线)的变换。类似地,反射可以被认为是变换基于一个 n-1 维对象。

尝试为小于 3d 的向量定义旋转以及在小于 2d 的向量中定义反射时会遇到麻烦。一般的做法可能是定义两个参数的函数;一个用于您正在旋转的矢量,一个“轴”表示(二维矢量的一个点)。

由于向量的长度(以及它所转换的对象)对于确定旋转或反射是否有意义很重要,因此这将是依赖类型的一个很好的用例(您可以在类型中指定向量的相对长度签名)。不幸的是,Haskell 还不完全支持它(尽管像 Idris 这样的一些实验性语言支持),所以你的选择相当于:

  • 将反射和旋转实现为当向量大小错误时失败的部分函数,
  • 实现一个更通用的函数,用于关于任何较小维度“轴”的转换(实际上不确定这是否可能),
  • 尝试一种具有依赖类型的语言(如果你想要那些类型安全的保证,或者
  • 通过您的实施获得创意

我想说在大多数情况下,Haskell 的学术血统使它对探索性数学有用,但它还不完美。

于 2016-02-29T05:19:02.403 回答