Skip to content

Commit

Permalink
Merge pull request #58 from jonyboi396825/add-1d-iszero
Browse files Browse the repository at this point in the history
Add 1d iszero
  • Loading branch information
jonathanhliu21 authored Jan 22, 2023
2 parents f183f4e + 340a9e9 commit da0c10a
Show file tree
Hide file tree
Showing 10 changed files with 172 additions and 33 deletions.
23 changes: 17 additions & 6 deletions docs/source/basic_usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,28 +36,28 @@ Below are examples of zero initialization and initializing with values.
svector::Vector2D v2d(2, 4); // <2, 4>
svector::Vector3D v3d(2, 4, 5); // <2, 4, 5>
Using ``make_vector()``
Using ``makeVector()``
~~~~~~~~~~~~~~~~~~~~~~~

You can also initialize a vector in a functional manner by using the ``make_vector()`` function. This function can be used to initialize a vector from an ``std::array``, ``std::vector``, or an initializer list. Note that if you are using ``make_vector`` to initialize from a ``std::vector`` or an initializer list, then you need to specify the number of dimensions as a template argument. If you are using an initializer list, you also need to specify the type of the vector elements.
You can also initialize a vector in a functional manner by using the ``makeVector()`` function. This function can be used to initialize a vector from an ``std::array``, ``std::vector``, or an initializer list. Note that if you are using ``makeVector()`` to initialize from a ``std::vector`` or an initializer list, then you need to specify the number of dimensions as a template argument. If you are using an initializer list, you also need to specify the type of the vector elements.

.. code-block:: cpp
std::array<double, 5> an_std_array = {{1, 2, 3, 5, 2}};
svector::Vector<5> vec_from_std_array =
svector::make_vector(an_std_array); // <1, 2, 3, 5, 2>
svector::makeVector(an_std_array); // <1, 2, 3, 5, 2>
std::vector<double> an_std_vector = {1};
svector::Vector2D vec_from_std_vector =
svector::make_vector<2>(an_std_vector); // <1, 0>
svector::makeVector<2>(an_std_vector); // <1, 0>
// If there are too few elements inside the std::vector, then the rest of the
// dimensions for the vector will be 0. If there are too many, then the vector
// truncates the dimensions.
svector::Vector2D vec_from_initializer_list =
svector::make_vector<2, double>({1, 4, 5}); // <1, 4>
svector::makeVector<2, double>({1, 4, 5}); // <1, 4>
// If there are too few or too many elements inside the initializer list, then
// make_vector() handles it the same way as it would handle a std::vector that
// makeVector() handles it the same way as it would handle a std::vector that
// has too few/many elements.
Printing
Expand Down Expand Up @@ -99,19 +99,27 @@ The properties are shown in the code snippet below.
std::cout << v3d.angle<svector::ALPHA>() << std::endl; // "1.268"
std::cout << v3d.angle<svector::BETA>() << std::endl; // "0.9322"
std::cout << v3d.angle<svector::GAMMA>() << std::endl; // "0.730"
// NOTE: the angle methods will result in undefined behavior if the magnitude
// of the vector is zero.
// set component values
v2d.x(4); // v2d is now <4, 4>
v3d.y(5);
v3d.z(3); // v3d is now <2, 5, 3>
// check if a vector is a zero vector (magnitude is zero)
std::cout << (v2d.isZero() ? "true" : "false") << std::endl; // false
std::cout << (v3d.isZero() ? "true" : "false") << std::endl; // false
Note that the functional equivalent for getting the angles of a 3D vector is slightly different:

.. code-block:: cpp
std::cout << svector::alpha(v3d) << std::endl; // alpha angle
std::cout << svector::beta(v3d) << std::endl; // beta angle
std::cout << svector::gamma(v3d) << std::endl; // gamma angle
// NOTE: the angle methods will result in undefined behavior if the magnitude
// of the vector is zero.
You can also access the x, y, and z components using the ``[]`` operator. In this case, the 0th index would correspond to the x-value, the 1st index would correspond to the y-value, and the 2nd index would correspond to the z-value. This also works on higher-dimensional vectors. There is no functional equivalent to this operator.

Expand Down Expand Up @@ -203,6 +211,9 @@ Below shows an example of vector normalization.
svector::Vector2D norm2D = unnorm2D.normalize(); // <0.6, 0.8>
svector::Vector3D norm3D = unnorm3D.normalize(); // <0.424, 0.566, 0.707>
**NOTE**: ``normalize()`` will result in undefined behavior if the magnitude of the vector is zero.

Rotation 2D
-----------

Expand Down
14 changes: 10 additions & 4 deletions example/basic_examples.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,19 @@ int main() {

std::array<double, 5> an_std_array = {{1, 2, 3, 5, 2}};
svector::Vector<5> vec_from_std_array =
svector::make_vector(an_std_array); // <1, 2, 3, 5, 2>
svector::makeVector(an_std_array); // <1, 2, 3, 5, 2>

std::vector<double> an_std_vector = {1};
svector::Vector2D vec_from_std_vector =
svector::make_vector<2>(an_std_vector); // <1, 0>
svector::makeVector<2>(an_std_vector); // <1, 0>
// If there are too few elements inside the std::vector, then the rest of the
// dimensions for the vector will be 0. If there are too many, then the vector
// truncates the dimensions.

svector::Vector2D vec_from_initializer_list =
svector::make_vector<2, double>({1, 4, 5}); // <1, 4>
svector::makeVector<2, double>({1, 4, 5}); // <1, 4>
// If there are too few or too many elements inside the initializer list, then
// make_vector() handles it the same way as it would handle a std::vector that
// makeVector() handles it the same way as it would handle a std::vector that
// has too few/many elements.

std::cout << vec_from_std_array.toString() << std::endl; // "<1, 2, 3, 5, 2>"
Expand Down Expand Up @@ -90,12 +90,18 @@ int main() {
std::cout << v3d.angle<svector::ALPHA>() << std::endl; // "1.268"
std::cout << v3d.angle<svector::BETA>() << std::endl; // "0.9322"
std::cout << v3d.angle<svector::GAMMA>() << std::endl; // "0.730"
// NOTE: the angle methods will result in undefined behavior if the magnitude
// of the vector is zero.

// set component values
v2d.x(4); // v2d is now <4, 4>
v3d.y(5);
v3d.z(3); // v3d is now <2, 5, 3>

// check if a vector is a zero vector (magnitude is zero)
std::cout << (v2d.isZero() ? "true" : "false") << std::endl; // false
std::cout << (v3d.isZero() ? "true" : "false") << std::endl; // false

std::cout << v2d.toString() << std::endl; // "<4.000, 4.000>"
std::cout << v3d.toString() << std::endl; // "<2.000, 5.000, 3.000>"

Expand Down
10 changes: 10 additions & 0 deletions include/simplevectors/core/vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,9 @@ template <std::size_t D, typename T = double> class Vector {
*
* Finds the unit vector with the same direction angle as the current vector.
*
* @note This method will result in undefined behavior if the vector is a zero
* vector (if the magnitude equals zero).
*
* @returns A new vector representing the normalized vector.
*/
Vector<D, T> normalize() const { return (*this) / this->magn(); }
Expand All @@ -386,6 +389,13 @@ template <std::size_t D, typename T = double> class Vector {
*/
constexpr std::size_t numDimensions() const { return D; }

/**
* Determines whether the current vector is a zero vector.
*
* @returns Whether the current vector is a zero vector.
*/
bool isZero() const { return this->magn() == 0; }

/**
* Gets a reference to a specific component of the vector given the dimension
* number.
Expand Down
3 changes: 3 additions & 0 deletions include/simplevectors/core/vector3d.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ class Vector3D : public Vec3_ {
*
* @see svector::AngleDir
*
* @note This method will result in undefined behavior if the vector is a zero
* vector (if the magnitude equals zero).
*
* @returns An angle representing the angle you specified.
*/
template <AngleDir D> double angle() const {
Expand Down
35 changes: 32 additions & 3 deletions include/simplevectors/embed.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,12 +354,22 @@ inline double angle(const EmbVec2D &vec) { return atan2(vec.y, vec.x); }
*
* Finds the unit vector with the same direction angle as the current vector.
*
* @note This method will result in undefined behavior if the vector is a zero
* vector (if the magnitude equals zero).
*
* @param vec A 2D vector.
*
* @returns Normalized vector.
*/
inline EmbVec2D normalize(const EmbVec2D &vec) { return vec / magn(vec); }

/**
* Determines whether a vector is a zero vector.
*
* @returns Whether the given vector is a zero vector.
*/
inline bool isZero(const EmbVec2D &vec) { return magn(vec) == 0; }

/**
* Rotates vector by a certain angle.
*
Expand Down Expand Up @@ -519,44 +529,63 @@ inline double magn(const EmbVec3D &vec) {
*
* Finds the unit vector with the same direction angle as the current vector.
*
* @note This method will result in undefined behavior if the vector is a zero
* vector (if the magnitude equals zero).
*
* @param vec A 3D vector.
*
* @returns Normalized vector.
*/
inline EmbVec3D normalize(const EmbVec3D &vec) { return vec / magn(vec); }

/**
* Determines whether a vector is a zero vector.
*
* @returns Whether the given vector is a zero vector.
*/
inline bool isZero(const EmbVec3D &vec) { return magn(vec) == 0; }

/**
* Gets α angle.
*
* α is the angle between the vector and the x-axis.
*
* @note This method will result in undefined behavior if the vector is a zero
* vector (if the magnitude equals zero).
*
* @param vec A 3D Vector.
*
* @returns α.
*/
inline double getAlpha(const EmbVec3D &vec) { return acos(vec.x / magn(vec)); }
inline double alpha(const EmbVec3D &vec) { return acos(vec.x / magn(vec)); }

/**
* Gets β angle.
*
* β is the angle between the vector and the y-axis.
*
* @note This method will result in undefined behavior if the vector is a zero
* vector (if the magnitude equals zero).
*
* @param vec A 3D Vector.
*
* @returns β.
*/
inline double getBeta(const EmbVec3D &vec) { return acos(vec.y / magn(vec)); }
inline double beta(const EmbVec3D &vec) { return acos(vec.y / magn(vec)); }

/**
* Gets γ angle.
*
* γ is the angle between the vector and the z-axis.
*
* @note This method will result in undefined behavior if the vector is a zero
* vector (if the magnitude equals zero).
*
* @param vec A 3D Vector.
*
* @returns γ.
*/
inline double getGamma(const EmbVec3D &vec) { return acos(vec.z / magn(vec)); }
inline double gamma(const EmbVec3D &vec) { return acos(vec.z / magn(vec)); }

/**
* Rotates around x-axis.
Expand Down
39 changes: 32 additions & 7 deletions include/simplevectors/embed.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,12 +365,22 @@ inline double angle(const Vec2D &vec) { return std::atan2(vec.y, vec.x); }
*
* Finds the unit vector with the same direction angle as the current vector.
*
* @note This method will result in undefined behavior if the vector is a zero
* vector (if the magnitude equals zero).
*
* @param vec A 2D vector.
*
* @returns Normalized vector.
*/
inline Vec2D normalize(const Vec2D &vec) { return vec / magn(vec); }

/**
* Determines whether a vector is a zero vector.
*
* @returns Whether the given vector is a zero vector.
*/
inline bool isZero(const Vec2D &vec) { return magn(vec) == 0; }

/**
* Rotates vector by a certain angle.
*
Expand Down Expand Up @@ -544,48 +554,63 @@ inline double magn(const Vec3D &vec) {
*
* Finds the unit vector with the same direction angle as the current vector.
*
* @note This method will result in undefined behavior if the vector is a zero
* vector (if the magnitude equals zero).
*
* @param vec A 3D vector.
*
* @returns Normalized vector.
*/
inline Vec3D normalize(const Vec3D &vec) { return vec / magn(vec); }

/**
* Determines whether a vector is a zero vector.
*
* @returns Whether the given vector is a zero vector.
*/
inline bool isZero(const Vec3D &vec) { return magn(vec) == 0; }

/**
* Gets α angle.
*
* α is the angle between the vector and the x-axis.
*
* @note This method will result in undefined behavior if the vector is a zero
* vector (if the magnitude equals zero).
*
* @param vec A 3D Vector.
*
* @returns α.
*/
inline double getAlpha(const Vec3D &vec) {
return std::acos(vec.x / magn(vec));
}
inline double alpha(const Vec3D &vec) { return std::acos(vec.x / magn(vec)); }

/**
* Gets β angle.
*
* β is the angle between the vector and the y-axis.
*
* @note This method will result in undefined behavior if the vector is a zero
* vector (if the magnitude equals zero).
*
* @param vec A 3D Vector.
*
* @returns β.
*/
inline double getBeta(const Vec3D &vec) { return std::acos(vec.y / magn(vec)); }
inline double beta(const Vec3D &vec) { return std::acos(vec.y / magn(vec)); }

/**
* Gets γ angle.
*
* γ is the angle between the vector and the z-axis.
*
* @note This method will result in undefined behavior if the vector is a zero
* vector (if the magnitude equals zero).
*
* @param vec A 3D Vector.
*
* @returns γ.
*/
inline double getGamma(const Vec3D &vec) {
return std::acos(vec.z / magn(vec));
}
inline double gamma(const Vec3D &vec) { return std::acos(vec.z / magn(vec)); }

/**
* Rotates around x-axis.
Expand Down
Loading

0 comments on commit da0c10a

Please sign in to comment.