diff options
author | Keuin <[email protected]> | 2022-04-11 15:19:05 +0800 |
---|---|---|
committer | Keuin <[email protected]> | 2022-04-11 15:25:40 +0800 |
commit | 32f44d39f01b62a51db177b6f3004ee0b835188d (patch) | |
tree | f645926e91a63636c321c18c68afca9ee4d31bd8 | |
parent | a15c8f6b3658095eb50da4bd75da697e37dbe033 (diff) |
Implement vec3 scalar and vector product, product by a scalar, get unit vector and print to ostream.
Fix wrong vec3 norm implementation.
-rw-r--r-- | test.cpp | 46 | ||||
-rw-r--r-- | vec.h | 64 |
2 files changed, 93 insertions, 17 deletions
@@ -24,11 +24,47 @@ TEST(Vec, VecMin) { ASSERT_EQ(d + (-e), f); } -TEST(Vec, VecCrossProduct) { +TEST(Vec, CrossProduct) { vec3i a{1, 1, 1}, b{2, 2, 2}, c{3, 4, 5}, d{6, 7, 8}, e{-3, -6, -3}; - ASSERT_EQ(a * b, vec3i{}); - ASSERT_EQ(c * d, e); + ASSERT_EQ(cross(a, b), vec3i{}); + ASSERT_EQ(a.cross(b), vec3i{}); + ASSERT_EQ(cross(c, d), e); + ASSERT_EQ(c.cross(d), e); - vec3d f{3.0, 4.0, 5.0}, g{6.0, 7.0, 8.0}, h{-3, -6, -3}; - ASSERT_EQ(f * g, h); + vec3d f{3, 4, 5}, g{6, 7, 8}, h{-3, -6, -3}; + ASSERT_EQ(cross(f, g), h); + ASSERT_EQ(f.cross(g), h); +} + +TEST(Vec, DotProduct) { + vec3i c{3, 4, 5}, d{6, 7, 8}; + int e = 18 + 28 + 40; + ASSERT_EQ(dot(c, d), e); + ASSERT_EQ(c.dot(d), e); + + vec3d f{3, 4, 5}, g{6, 7, 8}; + ASSERT_EQ(dot(f, g), e); + ASSERT_EQ(f.dot(g), e); +} + +TEST(Vec, MulByScalar) { + vec3i a{1, 1, 1}, b{2, 2, 2}; + vec3d c{7, 14, 21}, d{1, 2, 3}; + ASSERT_EQ(a * 2, b); + ASSERT_EQ(a / 0.5, b); + ASSERT_EQ(2 * a, b); + ASSERT_EQ(c * (1.0 / 7), d); + ASSERT_EQ(c / 7, d); + ASSERT_EQ(c / 7.0, d); +} + +TEST(Vec, Norm) { + vec3d a{1, 1, 1}, b{2, 2, 2}; + ASSERT_EQ(a.norm(), sqrt(3)); + ASSERT_EQ(b.norm(), sqrt(12)); +} + +TEST(Vec, UnitVec) { + vec3d a{1, 2, 2}, b{1.0 / 3, 2.0 / 3, 2.0 / 3}; + ASSERT_EQ(a.unit_vec(), b); }
\ No newline at end of file @@ -36,35 +36,75 @@ struct vec3 { } vec3 operator-(const vec3 &b) const { - return vec3{.x=x - b.x, .y=y - b.y, .z=z - b.z}; - } - - // cross product - vec3 operator*(const vec3 &b) const { - return vec3{.x=y * b.z - z * b.y, .y=x * b.z - z * b.x, .z=x * b.y - y * b.x}; + return *this + (-b); } bool operator==(const vec3 b) const { return eq(x, b.x) && eq(y, b.y) && eq(z, b.z); } - // dot product - int dot(const vec3 &b) const { + // dot product (aka inner product, or scalar product, producing a scalar) + T dot(const vec3 &b) const { return x * b.x + y * b.y + z * b.z; } + // cross product (aka outer product, or vector product, producing a vector) + vec3 cross(const vec3 &b) const { + return vec3{.x=y * b.z - z * b.y, .y=x * b.z - z * b.x, .z=x * b.y - y * b.x}; + } + // norm value - int norm(const int level = 2) const { + double norm(const int level = 2) const { if (level == 2) { - return std::abs(x * x + y * y + z * z); + return std::abs(sqrt(x * x + y * y + z * z)); } else if (level == 1) { - return std::abs(x + y + z); + return std::abs(x) + std::abs(y) + std::abs(z); } else { - return (int) std::abs(powl(x, level) + powl(y, level) + powl(z, level)); + return powl(powl(x, level) + powl(y, level) + powl(z, level), 1.0 / level); } } + + vec3 unit_vec() const { + return *this * (1.0 / norm()); + } }; +// print to ostream +template<typename T> +std::ostream &operator<<(std::ostream &out, const vec3<T> &vec) { + return out << "vec3[x=" << vec.x << ", y=" << vec.y << ", z=" << vec.z << ']'; +} + +// product vec3 by a scalar +template<typename T, typename S> +vec3<T> operator*(const vec3<T> &vec, const S &b) { + return vec3<T>{.x=(T) (vec.x * b), .y=(T) (vec.y * b), .z=(T) (vec.z * b)}; +} + +// product vec3 by a scalar +template<typename T, typename S> +vec3<T> operator*(const S &b, const vec3<T> &vec) { + return vec3<T>{.x=(T) (vec.x * b), .y=(T) (vec.y * b), .z=(T) (vec.z * b)}; +} + +// product vec3 by the inversion of a scalar (div by a scalar) +template<typename T, typename S> +vec3<T> operator/(const vec3<T> &vec, const S &b) { + return vec3<T>{.x=(T) (vec.x / b), .y=(T) (vec.y / b), .z=(T) (vec.z / b)}; +} + +// scalar product (inner product) +template<typename T> +T dot(const vec3<T> &a, const vec3<T> &b) { + return a.dot(b); +} + +// vector product (outer product) +template<typename T> +vec3<T> cross(const vec3<T> &a, const vec3<T> &b) { + return a.cross(b); +} + // 3-dim vector (int) using vec3i = vec3<int>; |