-- This source file is part of HGamer3D -- (A project to enable 3D game development in Haskell) -- For the latest info, see http://www.althainz.de/HGamer3D.html -- -- (c) 2011 Peter Althainz -- -- Licensed under the Apache License, Version 2.0 (the "License"); -- you may not use this file except in compliance with the License. -- You may obtain a copy of the License at -- -- http://www.apache.org/licenses/LICENSE-2.0 -- -- Unless required by applicable law or agreed to in writing, software -- distributed under the License is distributed on an "AS IS" BASIS, -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- See the License for the specific language governing permissions and -- limitations under the License. -- Quaternion.hs module HGamer3D.Data.Quaternion ( -- export Quaternion Type again Quaternion (Quaternion, qW, qV), quaternion, mulQ, conjQ, normQ, normalizeQ, dotQ, rotateVQ, fromRotationQ -- export all functions ) where import HGamer3D.Data.Vector3 import HGamer3D.Data.Vector4 (Vector4, vector4) data Quaternion = Quaternion { qW :: Float, qV :: Vector3 } deriving (Eq, Show) quaternion w x y z = Quaternion w (vector3 x y z) mulQ :: Quaternion -> Quaternion -> Quaternion mulQ q1 q2 = Quaternion ((w1 * w2) - (v1 `dotV3` v2)) ( (scaleV3 w1 v2) + (scaleV3 w2 v1) + (v1 `crossV3` v2) ) where w1 = qW q1 w2 = qW q2 v1 = qV q1 v2 = qV q2 conjQ :: Quaternion -> Quaternion conjQ q = Quaternion (qW q) (scaleV3 (-1.0) (qV q)) normQ :: Quaternion -> Float normQ q = sqrt $ dotQ q (conjQ q) normalizeQ :: Quaternion -> Quaternion normalizeQ q = Quaternion ( (qW q) / n ) ( (scaleV3 (1/n)) (qV q) ) where n = normQ q dotQ :: Quaternion -> Quaternion -> Float dotQ q1 q2 = (w1 * w2) + (v1 `dotV3` v2) where w1 = qW q1 w2 = qW q2 v1 = qV q1 v2 = qV q2 fromRotationQ :: Float -> Vector3 -> Quaternion fromRotationQ a v = Quaternion (cos h) (scaleV3 s v) where h = a/2.0 s = sin h rotateVQ :: Vector3 -> Quaternion -> Vector3 rotateVQ v q = qV (mulQ q (mulQ v' q')) where v' = Quaternion 0.0 v q' = conjQ q toVector4 :: Quaternion -> Vector4 toVector4 q = vector4 (v3X v) (v3Y v) (v3Z v) w where v = qV q w = qW q