<commit_before>{-# LANGUAGE CPP #-}
module SFML.Graphics.Transform
(
    Transform
,   m00, m10, m20
,   m01, m11, m21
,   m02, m12, m22
,   transform
,   idTransform
,   translate
,   rotate
,   rotateWithCenter
,   scale
,   scaleWithCenter
,   inverse
,   fastInverse
,   transformPoint
,   transformDir
,   transformRect
)
where


import SFML.Graphics.Rect
import SFML.Graphics.Types
import SFML.System.Vector2

import Data.List (foldl')
import Foreign.C.Types
import Foreign.Storable


sizeFloat = #{size float}


-- | Encapsulate a 3x3 transform matrix.
data Transform = Transform
    { m00 :: !Float, m10 :: !Float, m20 :: !Float
    , m01 :: !Float, m11 :: !Float, m21 :: !Float
    , m02 :: !Float, m12 :: !Float, m22 :: !Float
    }


instance Storable Transform where
    sizeOf _ = 9 * sizeFloat
    alignment _ = alignment (undefined :: CFloat)
    
    peek ptr = do
        m00 <- peekByteOff ptr 0
        m01 <- peekByteOff ptr sizeFloat
        m02 <- peekByteOff ptr $ 2*sizeFloat
        m10 <- peekByteOff ptr $ 3*sizeFloat
        m11 <- peekByteOff ptr $ 4*sizeFloat
        m12 <- peekByteOff ptr $ 5*sizeFloat
        m20 <- peekByteOff ptr $ 6*sizeFloat
        m21 <- peekByteOff ptr $ 7*sizeFloat
        m22 <- peekByteOff ptr $ 8*sizeFloat
        return $ Transform m00 m10 m20 m01 m11 m21 m02 m12 m22
    
    poke ptr (Transform m00 m10 m20 m01 m11 m21 m02 m12 m22) = do
        pokeByteOff ptr 0 m00
        pokeByteOff ptr sizeFloat m01
        pokeByteOff ptr (2*sizeFloat) m02
        pokeByteOff ptr (3*sizeFloat) m10
        pokeByteOff ptr (4*sizeFloat) m11
        pokeByteOff ptr (5*sizeFloat) m12
        pokeByteOff ptr (6*sizeFloat) m20
        pokeByteOff ptr (7*sizeFloat) m21
        pokeByteOff ptr (8*sizeFloat) m22


instance Num Transform where
    (Transform a00 a01 a02 a03 a04 a05 a06 a07 a08)
        + (Transform b00 b01 b02 b03 b04 b05 b06 b07 b08)
            = Transform (a00 + b00) (a01 + b01) (a02 + b02)
                        (a03 + b03) (a04 + b04) (a05 + b05)
                        (a06 + b06) (a07 + b07) (a08 + b08)
    
    (Transform a00 a01 a02 a03 a04 a05 a06 a07 a08)
        - (Transform b00 b01 b02 b03 b04 b05 b06 b07 b08)
            = Transform (a00 - b00) (a01 - b01) (a02 - b02)
                        (a03 - b03) (a04 - b04) (a05 - b05)
                        (a06 - b06) (a07 - b07) (a08 - b08)
    
    (Transform a00 a10 a20 a01 a11 a21 a02 a12 a22)
        * (Transform b00 b10 b20 b01 b11 b21 b02 b12 b22)
            = Transform (a00 * b00 + a10 * b01 + a20 * b02)
                        (a00 * b10 + a10 * b11 + a20 * b12)
                        (a00 * b20 + a10 * b21 + a20 * b22)
                        
                        (a01 * b00 + a11 * b01 + a21 * b02)
                        (a01 * b10 + a11 * b11 + a21 * b12)
                        (a01 * b20 + a11 * b21 + a21 * b22)
                        
                        (a02 * b00 + a12 * b01 + a22 * b02)
                        (a02 * b10 + a12 * b11 + a22 * b12)
                        (a02 * b20 + a12 * b21 + a22 * b22)
    
    abs (Transform a00 a01 a02 a03 a04 a05 a06 a07 a08) =
        (Transform (abs a00) (abs a01) (abs a02) (abs a03)
            (abs a04) (abs a05) (abs a06) (abs a07) (abs a08))
    
    signum (Transform a00 a01 a02 a03 a04 a05 a06 a07 a08) =
        (Transform (signum a00) (signum a01) (signum a02) (signum a03)
            (signum a04) (signum a05) (signum a06) (signum a07) (signum a08))
    
    fromInteger i = Transform i' i' i' i' i' i' i' i' i' where i' = fromInteger i


-- | Create a new transform from a matrix.
transform
    :: Float -- ^ Element (0, 0) of the matrix
    -> Float -- ^ Element (0, 1) of the matrix
    -> Float -- ^ Element (0, 2) of the matrix
    -> Float -- ^ Element (1, 0) of the matrix
    -> Float -- ^ Element (1, 1) of the matrix
    -> Float -- ^ Element (1, 2) of the matrix
    -> Float -- ^ Element (2, 0) of the matrix
    -> Float -- ^ Element (2, 1) of the matrix
    -> Float -- ^ Element (2, 2) of the matrix
    -> Transform

transform = Transform


-- | Identity transform.
idTransform :: Transform
idTransform = Transform 1 0 0 0 1 0 0 0 1


-- | Create a translation.
translate
    :: Float -- ^ Offset to apply on X axis
    -> Float -- ^ Offset to apply on Y axis
    -> Transform

translate x y = Transform
    1 0 x
    0 1 y
    0 0 1

-- | Create a rotation.
rotate
    :: Float -- ^ Rotation angle in degrees
    -> Transform

rotate deg =
    let rad = deg * pi / 180<commit_msg>transform -> createTransform<commit_after>{-# LANGUAGE CPP #-}
module SFML.Graphics.Transform
(
    Transform
,   m00, m10, m20
,   m01, m11, m21
,   m02, m12, m22
,   createTransform
,   idTransform
,   translate
,   rotate
,   rotateWithCenter
,   scale
,   scaleWithCenter
,   inverse
,   fastInverse
,   transformPoint
,   transformDir
,   transformRect
)
where


import SFML.Graphics.Rect
import SFML.Graphics.Types
import SFML.System.Vector2

import Data.List (foldl')
import Foreign.C.Types
import Foreign.Storable


sizeFloat = #{size float}


-- | Encapsulate a 3x3 transform matrix.
data Transform = Transform
    { m00 :: !Float, m10 :: !Float, m20 :: !Float
    , m01 :: !Float, m11 :: !Float, m21 :: !Float
    , m02 :: !Float, m12 :: !Float, m22 :: !Float
    }


instance Storable Transform where
    sizeOf _ = 9 * sizeFloat
    alignment _ = alignment (undefined :: CFloat)
    
    peek ptr = do
        m00 <- peekByteOff ptr 0
        m01 <- peekByteOff ptr sizeFloat
        m02 <- peekByteOff ptr $ 2*sizeFloat
        m10 <- peekByteOff ptr $ 3*sizeFloat
        m11 <- peekByteOff ptr $ 4*sizeFloat
        m12 <- peekByteOff ptr $ 5*sizeFloat
        m20 <- peekByteOff ptr $ 6*sizeFloat
        m21 <- peekByteOff ptr $ 7*sizeFloat
        m22 <- peekByteOff ptr $ 8*sizeFloat
        return $ Transform m00 m10 m20 m01 m11 m21 m02 m12 m22
    
    poke ptr (Transform m00 m10 m20 m01 m11 m21 m02 m12 m22) = do
        pokeByteOff ptr 0 m00
        pokeByteOff ptr sizeFloat m01
        pokeByteOff ptr (2*sizeFloat) m02
        pokeByteOff ptr (3*sizeFloat) m10
        pokeByteOff ptr (4*sizeFloat) m11
        pokeByteOff ptr (5*sizeFloat) m12
        pokeByteOff ptr (6*sizeFloat) m20
        pokeByteOff ptr (7*sizeFloat) m21
        pokeByteOff ptr (8*sizeFloat) m22


instance Num Transform where
    (Transform a00 a01 a02 a03 a04 a05 a06 a07 a08)
        + (Transform b00 b01 b02 b03 b04 b05 b06 b07 b08)
            = Transform (a00 + b00) (a01 + b01) (a02 + b02)
                        (a03 + b03) (a04 + b04) (a05 + b05)
                        (a06 + b06) (a07 + b07) (a08 + b08)
    
    (Transform a00 a01 a02 a03 a04 a05 a06 a07 a08)
        - (Transform b00 b01 b02 b03 b04 b05 b06 b07 b08)
            = Transform (a00 - b00) (a01 - b01) (a02 - b02)
                        (a03 - b03) (a04 - b04) (a05 - b05)
                        (a06 - b06) (a07 - b07) (a08 - b08)
    
    (Transform a00 a10 a20 a01 a11 a21 a02 a12 a22)
        * (Transform b00 b10 b20 b01 b11 b21 b02 b12 b22)
            = Transform (a00 * b00 + a10 * b01 + a20 * b02)
                        (a00 * b10 + a10 * b11 + a20 * b12)
                        (a00 * b20 + a10 * b21 + a20 * b22)
                        
                        (a01 * b00 + a11 * b01 + a21 * b02)
                        (a01 * b10 + a11 * b11 + a21 * b12)
                        (a01 * b20 + a11 * b21 + a21 * b22)
                        
                        (a02 * b00 + a12 * b01 + a22 * b02)
                        (a02 * b10 + a12 * b11 + a22 * b12)
                        (a02 * b20 + a12 * b21 + a22 * b22)
    
    abs (Transform a00 a01 a02 a03 a04 a05 a06 a07 a08) =
        (Transform (abs a00) (abs a01) (abs a02) (abs a03)
            (abs a04) (abs a05) (abs a06) (abs a07) (abs a08))
    
    signum (Transform a00 a01 a02 a03 a04 a05 a06 a07 a08) =
        (Transform (signum a00) (signum a01) (signum a02) (signum a03)
            (signum a04) (signum a05) (signum a06) (signum a07) (signum a08))
    
    fromInteger i = Transform i' i' i' i' i' i' i' i' i' where i' = fromInteger i


-- | Create a new transform from a matrix.
createTransform
    :: Float -- ^ Element (0, 0) of the matrix
    -> Float -- ^ Element (0, 1) of the matrix
    -> Float -- ^ Element (0, 2) of the matrix
    -> Float -- ^ Element (1, 0) of the matrix
    -> Float -- ^ Element (1, 1) of the matrix
    -> Float -- ^ Element (1, 2) of the matrix
    -> Float -- ^ Element (2, 0) of the matrix
    -> Float -- ^ Element (2, 1) of the matrix
    -> Float -- ^ Element (2, 2) of the matrix
    -> Transform

createTransform = Transform


-- | Identity transform.
idTransform :: Transform
idTransform = Transform 1 0 0 0 1 0 0 0 1


-- | Create a translation.
translate
    :: Float -- ^ Offset to apply on X axis
    -> Float -- ^ Offset to apply on Y axis
    -> Transform

translate x y = Transform
    1 0 x
    0 1 y
    0 0 1

-- | Create a rotation.
rotate
    :: Float -- ^ Rotation angle in degrees
    -> Transform

rotate deg =
    let rad = deg * pi / 180
{'fraction_non_alphanumeric': 0.10328535325788375, 'fraction_numerical': 0.11537193714976376, 'mean_word_length': 1.7800855222968845, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 28, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 24, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4981528', 'n_tokens_mistral': 3819, 'n_tokens_neox': 3156, 'n_words': 1102}