correct (and much better) docs

This commit is contained in:
Corwin 2022-10-09 16:59:58 +01:00
parent ed1e8bcbdc
commit 89107f7a4e

View file

@ -7,16 +7,79 @@
//! Affine matricies are used in two places on the GBA, for affine backgrounds //! Affine matricies are used in two places on the GBA, for affine backgrounds
//! and for affine objects. //! and for affine objects.
//! //!
//! # Linear Algebra basics //! # Linear Algebra
//! As a matrix, they can be manipulated using linear algebra, although you //! As a matrix, they can be manipulated using linear algebra. The short version
//! shouldn't need to know linear algebra to use this apart from a few things //! of this section is to beware that the matrix is the inverse of the normal
//! transformation matricies.
//! //!
//! If `A` and `B` are matricies, then matrix `C = A * B` represents the //! One quick thing to point out at the start as it will become very relevant is
//! transformation `A` performed on `B`, or alternatively `C` is transformation //! that matrix-matrix multiplication is not commutative, meaning swapping the
//! `B` followed by transformation `A`. //! order changes the result, or **A** × **B** ≢ **B** × **A**. However,
//! matricies are, at least in the case they are used here, associative, meaning
//! (**AB**)**C** = **A**(**BC**).
//! //!
//! Additionally matrix multiplication is not commutative, meaning swapping the //! ## Normal (wrong on GBA!) transformation matricies
//! order changes the result, or `A * B ≢ B * A`. //!
//! As a start, normal transformation matricies will transform a shape from it's
//! original position to it's new position. Generally when people talk about
//! transformation matricies they are talking about them in this sense.
//!
//! > If **A** and **B** are transformation matricies, then matrix **C** = **A**
//! > × **B** represents the transformation **A** performed on **B**, or
//! > alternatively **C** is transformation **B** followed by transformation
//! > **A**.
//!
//! This is not what they represent on the GBA! If you are looking up more
//! information about tranformation matricies bear this in mind.
//!
//! ## Correct (on GBA) transformation matricies
//!
//! On the GBA, the affine matrix works the other way around. The GBA wants to
//! know for each pixel what colour it should render, to do this it applies the
//! affine transformation matrix to the pixel it is rendering to lookup correct
//! pixel in the texture.
//!
//! This describes the inverse of the previously given transformation matricies.
//!
//! Above I described the matrix **C** = **A** × **B**, but what the GBA wants
//! is the inverse of **C**, or **C**<sup>-1</sup> = (**AB**)<sup>-1</sup> =
//! **B**<sup>-1</sup> × **A**<sup>-1</sup>. This means that if we have the
//! matricies **I** and **J** in the form the GBA expects then
//!
//! > Transformation **K** = **I** × **J** is the transformation **I** followed
//! > by the transformation **J**.
//!
//! Beware if you are used to the other way around!
//!
//! ## Example, rotation around the center
//!
//! To rotate something around its center, you will need to move the thing such
//! that the center is at (0, 0) and then you can rotate it. After that you can
//! move it where you actually want it.
//!
//! These can be done in the order I stated, **A** = **Move To Origin** ×
//! **Rotate** × **Move to Final Position**. Or in code,
//!
//! ```rust,no_run
//! # #![no_std]
//! # #![no_main]
//! use agb::fixnum::{Vector2D, Num, num};
//! use agb::display::affine::AffineMatrix;
//!
//! # fn foo(_gba: &mut agb::Gba) {
//! // size of our thing is 10 pixels by 10 pixels
//! let size_of_thing: Vector2D<Num<i32, 8>> = (10, 10).into()
//! // rotation by a quarter turn
//! let rotation: Num<i32, 8> = num!(0.25);
//! // the final position
//! let position: Vector2D<Num<i32, 8>> = (100, 100).into();
//!
//! // now lets calculate the final transformation matrix!
//! let a = AffineMatrix::from_translation(-size_of_thing / 2)
//! * AffineMatrix::from_rotation(rotation)
//! * AffineMatrix::from_translation(position);
//! # }
//! ```
use core::{ use core::{
convert::TryFrom, convert::TryFrom,