简体   繁体   中英

how to define n-dimensional vector rotation and reflection in haskell?

How do I define vector rotation and reflection in general where the function would work in n dimensions in Haskell?

Currently I have the dot product, normalization and projection done but stuck on reflection and rotation.

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`)))

I've been searhing for days now but it seems that using Haskell to understand mathematics can sometimes cause problems when there is no clear code (or no code at all) and the only tutorials on n-dimensional vectors go past my knowledge in mathematics.

Regarding the mathematical aspects of n-dimensional rotations, I might recommend the publications of Andrew J. Hanson of the Computer Science Department of the University of Indiana. In particular:

“Rotations for N-Dimensional Computer Graphics” https://www.cs.indiana.edu/pub/techreports/TR406.pdf

That paper is a successor to “Geometry for N-Dimensional Computer Graphics” https://classes.soe.ucsc.edu/cmps161/Winter14/papers/pv/ggndgeom.pdf

The mathematics require a knowledge of vector arithmetic and linear algebra, but if you're going to be performing N-dimensional transformations, this is the recommended way to do the math.

The mathematics should be able to get us most of the way here; a rotation in n-dimensional space can be thought of as a transformation based about an n-2 dimensional object (ie. a point on a plane, or a line in 3-space. Similarly, a reflection can be thought of as a transformation based around an n-1 dimensional object.

You'll have trouble trying to define rotations for anything less than a 3d vector, and reflections in anything less than a 2d vector. The general approach may be to define a function of two parameters; one for the vector you're rotating, and one "axis" representation (a point for a 2d vector).

Since the length of the vector (and the object it's transforming about) is important in determining whether a rotation or reflection even make sense, this would be a good use case for dependent typing (you could specify the relative length of the vectors in the type signatures). Unfortunately, Haskell doesn't support that in full yet (though some experimental languages like Idris do), so your options amount to:

  • Implement reflections and rotations as partial functions that fail when the sizes of the vectors are wrong,
  • Implement a single more general function for transformations about any smaller dimensional "axis" (not actually sure if this is possible),
  • Try a language with dependent types (if you want those guarantees of type safety, or
  • Get creative with your implementations

I'd say in most cases, Haskell's academic pedigree makes it useful for exploratory mathematics, but it ain't perfect yet.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM