Next few commits will add requirement for "strongly typed" angles in all
function parameters, e.g.:
Matrix3::rotation(24.0_degf);
Math::sin(1.047_radf);
The purpose is to make angle entering less error-prone, e.g. not passing
degrees when radians should be etc.
Hopefully this is properly implemented and properly named. On the other
hand, having length everywhere (vectors, quaternions, complex numbers)
and norm only at one place is inconsistent.
It's now possible to conveniently transform 2D vectors and points with
3x3 matrices and 3D vectors/points with 4x4 matrices. Previous most
low-level solution:
Matrix4 m;
Vector3 v;
Vector3 a = (m*Vector4(v, 1.0f)).xyz();
Vector4 b = (m*Vector4(v, 0.0f)).xyz();
Another, more generalized solution for points was with Point2D/Point3D,
adding a lot of confusion (what is that class and what does .vector()?):
Vector3 a = (m*Point3D(v)).vector();
And the worst solution was with generic 2D/3D code (WTF!):
auto a = (m*typename DimensionTraits::PointType(v)).vector();
Now it is just this, similar for both dimensions:
Vector3 a = m.transformPoint(v);
Vector3 b = m.transformVector(v);
Note that transformation three-component vectors with 3x3 matrices or
four-component vectors with 4x4 matrices is easy enough so it doesn't
need any special convenience functions whatsoever:
Vector3 c = m.rotation()*v;
It is now possible to implicitly create one-element Vector and also
explicitly fill more-element Vector with one value without any ambiguous
overload conflicts:
Vector<1, int> a1 = 1; // calls implicit constructor
//Vector<3, int> a3 = 1; // error!
Vector<1, int> b1(1); // still calls the implicit constructor, the
// explicit is disabled for one-element vector
Vector<3, int> b3(1); // calls the explicit "filling" constructor,
// the implicit is disabled for only one argument
The downside of this is that now specifying improper element count in
constructor doesn't lead to static_assert with human readable error, but
rather cryptic "no match" error.