Browse Source

doc: compiling Transformations page code snippets.

pull/233/head
Vladimír Vondruš 8 years ago
parent
commit
b3208e8f75
  1. 1
      doc/snippets/CMakeLists.txt
  2. 211
      doc/snippets/MagnumMath.cpp
  3. 108
      doc/transformations.dox

1
doc/snippets/CMakeLists.txt

@ -36,6 +36,7 @@ endif()
add_library(snippets STATIC add_library(snippets STATIC
plugins.cpp plugins.cpp
Magnum.cpp Magnum.cpp
MagnumMath.cpp
MagnumMeshTools.cpp MagnumMeshTools.cpp
MagnumShaders.cpp MagnumShaders.cpp
MagnumText.cpp) MagnumText.cpp)

211
doc/snippets/MagnumMath.cpp

@ -0,0 +1,211 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "Magnum/Magnum.h"
#include "Magnum/Math/DualComplex.h"
#include "Magnum/Math/DualQuaternion.h"
#include "Magnum/Math/Algorithms/GramSchmidt.h"
using namespace Magnum;
using namespace Magnum::Math::Literals;
int main() {
{
/* [transformations-rotation2D] */
auto a = Matrix3::rotation(23.0_degf);
auto b = Complex::rotation(Rad(Constants::piHalf()));
auto c = DualComplex::rotation(-1.57_radf);
/* [transformations-rotation2D] */
static_cast<void>(a);
static_cast<void>(b);
static_cast<void>(c);
}
{
Rad angle;
/* [transformations-rotation3D] */
auto a = Quaternion::rotation(60.0_degf, Vector3::xAxis());
auto b = DualQuaternion::rotation(-1.0_degf, Vector3(1.0f, 0.5f, 3.0f).normalized());
auto c = Matrix4::rotationZ(angle);
/* [transformations-rotation3D] */
static_cast<void>(a);
static_cast<void>(b);
static_cast<void>(c);
}
{
/* [transformations-translation2D] */
auto a = Matrix3::translation(Vector2::xAxis(-5.0f));
auto b = DualComplex::translation({-1.0f, 0.5f});
/* [transformations-translation2D] */
static_cast<void>(a);
static_cast<void>(b);
}
{
Vector3 vector;
/* [transformations-translation3D] */
auto a = Matrix4::translation(vector);
auto b = DualQuaternion::translation(Vector3::zAxis(1.3f));
/* [transformations-translation3D] */
static_cast<void>(a);
static_cast<void>(b);
}
{
/* [transformations-scaling] */
auto a = Matrix3::scaling(Vector2::xScale(2.0f));
auto b = Matrix4::scaling({2.0f, -2.0f, 1.5f});
auto c = Matrix4::scaling(Vector3(10.0f));
/* [transformations-scaling] */
static_cast<void>(a);
static_cast<void>(b);
static_cast<void>(c);
}
{
Vector3 axis;
/* [transformations-reflection] */
auto a = Matrix3::reflection(Vector2::yAxis());
auto b = Matrix4::reflection(axis.normalized());
/* [transformations-reflection] */
static_cast<void>(a);
static_cast<void>(b);
}
{
/* [transformations-projection] */
auto a = Matrix3::projection({4.0f, 3.0f});
auto b = Matrix4::orthographicProjection({4.0f, 3.0f}, 0.001f, 100.0f);
auto c = Matrix4::perspectiveProjection(35.0_degf, 1.333f, 0.001f, 100.0f);
/* [transformations-projection] */
static_cast<void>(a);
static_cast<void>(b);
static_cast<void>(c);
}
{
/* [transformations-composing] */
auto a = DualComplex::translation(Vector2::yAxis(2.0f))*
DualComplex::rotation(25.0_degf);
auto b = Matrix4::translation(Vector3::yAxis(5.0f))*
Matrix4::rotationY(25.0_degf);
/* [transformations-composing] */
static_cast<void>(a);
static_cast<void>(b);
}
{
/* [transformations-transform2D] */
auto transformation = Matrix3::rotation(-30.0_degf)*Matrix3::scaling(Vector2(3.0f));
Vector2 transformed = transformation.transformVector({1.5f, -7.9f});
/* [transformations-transform2D] */
static_cast<void>(transformed);
}
{
/* [transformations-transform3D] */
auto transformation = DualQuaternion::rotation(-30.0_degf, Vector3::xAxis())*
DualQuaternion::translation(Vector3::yAxis(3.0f));
Vector3 transformed = transformation.transformPointNormalized({1.5f, 3.0f, -7.9f});
/* [transformations-transform3D] */
static_cast<void>(transformed);
}
{
/* [transformations-properties] */
Matrix4 transformation;
Matrix3x3 rotationScaling = transformation.rotationScaling();
Vector3 up = transformation.up();
Vector3 right = transformation.right();
Matrix3 b;
Matrix2x2 rotation = b.rotation();
Float xTranslation = b.translation().x();
/* [transformations-properties] */
/* [transformations-recreate] */
Matrix3 c = Matrix3::from(rotation, {1.0f, 3.0f});
/* [transformations-recreate] */
static_cast<void>(rotationScaling);
static_cast<void>(up);
static_cast<void>(right);
static_cast<void>(xTranslation);
static_cast<void>(c);
}
{
/* [transformations-properties-complex-quat] */
DualComplex a;
Rad rotationAngle = a.rotation().angle();
Vector2 translation = a.translation();
Quaternion b;
Vector3 rotationAxis = b.axis();
/* [transformations-properties-complex-quat] */
static_cast<void>(rotationAngle);
static_cast<void>(translation);
static_cast<void>(rotationAxis);
}
{
/* [transformations-properties-complex-quat-to-matrix] */
Quaternion a;
auto rotation = Matrix4::from(a.toMatrix(), {});
DualComplex b;
Matrix3 transformation = b.toMatrix();
/* [transformations-properties-complex-quat-to-matrix] */
static_cast<void>(rotation);
static_cast<void>(transformation);
}
{
/* [transformations-properties-complex-quat-from-matrix] */
Matrix3 rotation;
auto a = Complex::fromMatrix(rotation.rotationScaling());
Matrix4 transformation;
auto b = DualQuaternion::fromMatrix(transformation);
/* [transformations-properties-complex-quat-from-matrix] */
static_cast<void>(a);
static_cast<void>(b);
}
{
/* [transformations-normalization-matrix] */
Matrix4 transformation;
Math::Algorithms::gramSchmidtOrthonormalizeInPlace(transformation);
/* [transformations-normalization-matrix] */
}
{
/* [transformations-normalization-quat] */
DualQuaternion transformation;
transformation = transformation.normalized();
/* [transformations-normalization-quat] */
}
}

108
doc/transformations.dox

@ -87,11 +87,7 @@ you don't need to worry about them in initialization.
and rotation transformation can be created by calling @ref Matrix3::rotation(), and rotation transformation can be created by calling @ref Matrix3::rotation(),
@ref Complex::rotation() or @ref DualComplex::rotation(), for example: @ref Complex::rotation() or @ref DualComplex::rotation(), for example:
@code{.cpp} @snippet MagnumMath.cpp transformations-rotation2D
auto a = Matrix3::rotation(23.0_degf);
auto b = Complex::rotation(Rad(Constants::piHalf()));
auto c = DualComplex::rotation(-1.57_radf);
@endcode
3D rotation is represented by angle and (three-dimensional) axis. The rotation 3D rotation is represented by angle and (three-dimensional) axis. The rotation
can be created by calling @ref Matrix4::rotation(), @ref Quaternion::rotation() can be created by calling @ref Matrix4::rotation(), @ref Quaternion::rotation()
@ -102,11 +98,7 @@ Matrix representation has also @ref Matrix4::rotationX(),
@ref Matrix4::rotationY() and @ref Matrix4::rotationZ() which are faster than @ref Matrix4::rotationY() and @ref Matrix4::rotationZ() which are faster than
using the generic function for rotation around primary axes. Examples: using the generic function for rotation around primary axes. Examples:
@code{.cpp} @snippet MagnumMath.cpp transformations-rotation3D
auto a = Quaternion::rotation(60.0_degf, Vector3::xAxis());
auto b = DualQuaternion::rotation(-1.0_degf, Vector3(1.0f, 0.5f, 3.0f).normalized());
auto c = Matrix4::rotationZ(angle);
@endcode
Rotations are always around origin. Rotation about arbitrary point can be done Rotations are always around origin. Rotation about arbitrary point can be done
by applying translation to have the point at origin, performing the rotation and by applying translation to have the point at origin, performing the rotation and
@ -120,19 +112,13 @@ then translating back. Read below for more information.
@ref Vector2::xAxis() or @ref Vector2::yAxis() to translate only along given @ref Vector2::xAxis() or @ref Vector2::yAxis() to translate only along given
axis. Examples: axis. Examples:
@code{.cpp} @snippet MagnumMath.cpp transformations-translation2D
auto a = Matrix3::translation(Vector2::xAxis(-5.0f));
auto b = DualComplex::translation({-1.0f, 0.5f});
@endcode
3D translation is defined by three-dimensional vector and can be created with 3D translation is defined by three-dimensional vector and can be created with
@ref Matrix4::translation() or @ref DualQuaternion::translation(). You can use @ref Matrix4::translation() or @ref DualQuaternion::translation(). You can use
@ref Vector3::xAxis() and friends also here. Examples: @ref Vector3::xAxis() and friends also here. Examples:
@code{.cpp} @snippet MagnumMath.cpp transformations-translation3D
auto a = Matrix4::translation(vector);
auto b = DualQuaternion::translation(Vector3::zAxis(1.3f));
@endcode
@subsection transformations-scaling Scaling and reflection @subsection transformations-scaling Scaling and reflection
@ -143,11 +129,7 @@ or their 2D counterparts to scale along one axis and leave the rest unchanged
or call explicit one-parameter vector constructor to scale uniformly on all or call explicit one-parameter vector constructor to scale uniformly on all
axes. Examples: axes. Examples:
@code{.cpp} @snippet MagnumMath.cpp transformations-scaling
auto a = Matrix3::scaling(Vector2::xScale(2.0f));
auto b = Matrix4::scaling({2.0f, -2.0f, 1.5f});
auto c = Matrix4::scaling(Vector3(10.0f));
@endcode
Reflections are defined by normal along which to reflect (i.e., two- or Reflections are defined by normal along which to reflect (i.e., two- or
three-dimensional vector of unit length) and they are also represented by three-dimensional vector of unit length) and they are also represented by
@ -155,10 +137,7 @@ matrices. Reflection is created with @ref Matrix3::reflection() or
@ref Matrix4::reflection(). You can use @ref Vector3::xAxis() and friends also @ref Matrix4::reflection(). You can use @ref Vector3::xAxis() and friends also
here. Examples: here. Examples:
@code{.cpp} @snippet MagnumMath.cpp transformations-reflection
auto a = Matrix3::reflection(Vector2::yAxis());
auto b = Matrix4::reflection(axis.normalized());
@endcode
Scaling and reflection is also done relative to origin, you can use method Scaling and reflection is also done relative to origin, you can use method
mentioned above to scale or reflect around arbitrary point. mentioned above to scale or reflect around arbitrary point.
@ -179,11 +158,7 @@ unit cube, and perspective projection. Perspective projection is created with
aspect ratio and distance to near and far plane of view frustum or by size of aspect ratio and distance to near and far plane of view frustum or by size of
near plane, its distance and distance to far plane. Some examples: near plane, its distance and distance to far plane. Some examples:
@code{.cpp} @snippet MagnumMath.cpp transformations-projection
auto a = Matrix3::projection({4.0f, 3.0f});
auto b = Matrix4::orthographicProjection({4.0f, 3.0f, 100.0f});
auto c = Matrix4::perspectiveProjection(35.0_degf, 1.333f, 0.001f, 100.0f);
@endcode
@section transformations-composing Composing and inverting transformations @section transformations-composing Composing and inverting transformations
@ -194,12 +169,7 @@ transformation on the right-hand side of multiplication is applied first, the
transformation on the left-hand side is applied second. For example, rotation transformation on the left-hand side is applied second. For example, rotation
followed by translation is done like this: followed by translation is done like this:
@code{.cpp} @snippet MagnumMath.cpp transformations-composing
auto a = DualComplex::translation(Vector2::yAxis(2.0f))*
DualComplex::rotation(25.0_degf);
auto b = Matrix4::translation(Vector3::yAxis(5.0f))*
Matrix4::rotationY(25.0_degf);
@endcode
Inverse transformation can be computed using @ref Matrix3::inverted(), Inverse transformation can be computed using @ref Matrix3::inverted(),
@ref Matrix4::inverted(), @ref Complex::inverted(), @ref Quaternion::inverted(), @ref Matrix4::inverted(), @ref Complex::inverted(), @ref Quaternion::inverted(),
@ -221,21 +191,14 @@ using @ref Matrix4::transformVector() and @ref Quaternion::transformVector().
For transformation with normalized quaternion you can use faster alternative For transformation with normalized quaternion you can use faster alternative
@ref Quaternion::transformVectorNormalized(). Example: @ref Quaternion::transformVectorNormalized(). Example:
@code{.cpp} @snippet MagnumMath.cpp transformations-transform2D
auto transformation = Matrix3::rotation(-30.0_degf)*Matrix3::scaling(Vector2(3.0f));
Vector2 transformed = transformation.transformVector({1.5f, -7.9f});
@endcode
Point transformation involves also translation, in 2D is done with Point transformation involves also translation, in 2D is done with
@ref Matrix3::transformPoint() and @ref DualComplex::transformPoint(), in 3D @ref Matrix3::transformPoint() and @ref DualComplex::transformPoint(), in 3D
with @ref Matrix4::transformPoint() and @ref DualQuaternion::transformPoint(). with @ref Matrix4::transformPoint() and @ref DualQuaternion::transformPoint().
Also here you can use faster alternative @ref DualQuaternion::transformPointNormalized(): Also here you can use faster alternative @ref DualQuaternion::transformPointNormalized():
@code{.cpp} @snippet MagnumMath.cpp transformations-transform3D
auto transformation = DualQuaternion::rotation(-30.0_degf, Vector3::xAxis())*
DualQuaternion::translation(Vector3::yAxis(3.0f));
Vector3 transformed = transformation.transformPointNormalized({1.5f, 3.0f, -7.9f});
@endcode
@section transformations-properties Transformation properties and conversion @section transformations-properties Transformation properties and conversion
@ -243,16 +206,7 @@ It is possible to extract some transformation properties from transformation
matrices, particularly translation vector, rotation/scaling part of the matrix matrices, particularly translation vector, rotation/scaling part of the matrix
(or pure rotation if the matrix has uniform scaling) and also base vectors: (or pure rotation if the matrix has uniform scaling) and also base vectors:
@code{.cpp} @snippet MagnumMath.cpp transformations-properties
Matrix4 a;
auto rotationScaling = transformation.rotationScaling();
Vector3 up = transformation.up();
Vector3 right = transformation.right();
Matrix3 b;
auto rotation = b.rotation();
Float xTranslation = b.translation().x();
@endcode
Extracting scaling and rotation from arbitrary transformation matrices is Extracting scaling and rotation from arbitrary transformation matrices is
harder and can be done using @ref Math::Algorithms::svd(). Extracting rotation harder and can be done using @ref Math::Algorithms::svd(). Extracting rotation
@ -262,9 +216,7 @@ complex number or quaternion, see below.
You can also recreate transformation matrix from rotation and translation You can also recreate transformation matrix from rotation and translation
parts: parts:
@code{.cpp} @snippet MagnumMath.cpp transformations-recreate
Matrix3 c = Matrix3::from(rotation, {1.0f, 3.0f});
@endcode
Complex numbers and quaternions are far better in this regard and they allow Complex numbers and quaternions are far better in this regard and they allow
you to extract rotation angle using @ref Complex::angle() or you to extract rotation angle using @ref Complex::angle() or
@ -273,40 +225,21 @@ Their dual versions allow to extract both rotation and translation part using
@ref DualComplex::rotation() const, @ref DualQuaternion::rotation() const, @ref DualComplex::rotation() const, @ref DualQuaternion::rotation() const,
@ref DualComplex::translation() const and @ref DualQuaternion::translation() const. @ref DualComplex::translation() const and @ref DualQuaternion::translation() const.
@code{.cpp} @snippet MagnumMath.cpp transformations-properties-complex-quat
DualComplex a;
Rad rotationAngle = a.rotation().angle();
Vector2 translation = a.translation();
Quaternion b;
Vector3 rotationAxis = b.axis();
@endcode
You can convert Complex and Quaternion to rotation matrix using You can convert Complex and Quaternion to rotation matrix using
@ref Complex::toMatrix() and @ref Quaternion::toMatrix() or their dual version @ref Complex::toMatrix() and @ref Quaternion::toMatrix() or their dual version
to rotation and translation matrix using @ref DualComplex::toMatrix() and to rotation and translation matrix using @ref DualComplex::toMatrix() and
@ref DualQuaternion::toMatrix(): @ref DualQuaternion::toMatrix():
@code{.cpp} @snippet MagnumMath.cpp transformations-properties-complex-quat-to-matrix
Quaternion a;
auto rotation = Matrix4::from(a.toMatrix(), {});
DualComplex b;
Matrix3 transformation = b.toMatrix();
@endcode
Conversion the other way around is possible only from rotation matrices using Conversion the other way around is possible only from rotation matrices using
@ref Complex::fromMatrix() or @ref Quaternion::fromMatrix() and from rotation @ref Complex::fromMatrix() or @ref Quaternion::fromMatrix() and from rotation
and translation matrices using @ref DualComplex::fromMatrix() and and translation matrices using @ref DualComplex::fromMatrix() and
@ref DualQuaternion::fromMatrix(): @ref DualQuaternion::fromMatrix():
@code{.cpp} @snippet MagnumMath.cpp transformations-properties-complex-quat-from-matrix
Matrix3 rotation;
auto a = Complex::fromMatrix(rotation.rotationScaling());
Matrix4 transformation;
auto b = DualQuaternion::fromMatrix(transformation);
@endcode
@section transformations-interpolation Transformation interpolation @section transformations-interpolation Transformation interpolation
@ -326,10 +259,7 @@ can be reorthogonalized using @ref Math::Algorithms::gramSchmidtOrthogonalize()
scaling). You can also use @ref Math::Algorithms::svd() to more precisely (but scaling). You can also use @ref Math::Algorithms::svd() to more precisely (but
way more slowly) account for the drift. Example: way more slowly) account for the drift. Example:
@code{.cpp} @snippet MagnumMath.cpp transformations-normalization-matrix
Matrix4 transformation;
Math::Algorithms::gramSchmidtOrthonormalizeInPlace(transformation);
@endcode
For quaternions and complex number this problem can be solved far more easily For quaternions and complex number this problem can be solved far more easily
using @ref Complex::normalized(), @ref Quaternion::normalized(), using @ref Complex::normalized(), @ref Quaternion::normalized(),
@ -337,9 +267,7 @@ using @ref Complex::normalized(), @ref Quaternion::normalized(),
Transformation quaternions and complex numbers are always of unit length, thus Transformation quaternions and complex numbers are always of unit length, thus
normalizing them reduces the drift. normalizing them reduces the drift.
@code{.cpp} @snippet MagnumMath.cpp transformations-normalization-quat
DualQuaternion transformation;
transformation = transformation.normalized();
@endcode
*/ */
} }

Loading…
Cancel
Save