-- This module provides basic algebra with 2d-vectors and geomtric shapes
-- Copyright (C) 2015, Sebastian Jordan

-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.

-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.

-- You should have received a copy of the GNU General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.

-- | This module contains a type class that can be used to modell
-- data, that can be rotated by a given angle.

module Geom2d.Rotation

where

-- | Modells data that has an angle and can be rotated.  
class Rotation p where
  -- | An object can return the orientation in space.  If the object
  -- returns its orientation it should hold the following law:
  --
  -- prop> fromMaybe True $ (==) <$> angle (r `rotate` x) <*> ((subtract pi).((`mod'` (2*pi)).(+pi).(+r)) <$> angle x)
  --
  -- Also angle should never return a value bigger than `pi` and
  -- smaller than `- pi`
  --
  -- prop> fromMaybe True (fmap (\a -> a >= (- pi) && a <= pi) (angle x))
  --
  -- The default implementation is
  -- 
  -- @
  -- angle _ = Nothing
  -- @
  angle :: (Floating a, RealFloat a, Ord a) => p a -> Maybe a
  angle _ = Nothing
  -- | Should rotate an object by a given angle.
  rotate :: (Floating a) => a -> p a -> p a