diff options
author | Bastiaan Olij <mux213@gmail.com> | 2021-09-01 13:11:10 +1000 |
---|---|---|
committer | Bastiaan Olij <mux213@gmail.com> | 2021-09-27 23:08:10 +1000 |
commit | 46c63af715cf42a6e27feb48a3e7ed6d6dd9458c (patch) | |
tree | 14b3049fc155209d617b89fb3e45b95269519f9f /src/variant/vector2.cpp | |
parent | 3a5bd210921ac668949e20c494976660a986ea4a (diff) | |
download | redot-cpp-46c63af715cf42a6e27feb48a3e7ed6d6dd9458c.tar.gz |
Re-introduce build-in type code for core types
Diffstat (limited to 'src/variant/vector2.cpp')
-rw-r--r-- | src/variant/vector2.cpp | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/src/variant/vector2.cpp b/src/variant/vector2.cpp new file mode 100644 index 0000000..a91bdde --- /dev/null +++ b/src/variant/vector2.cpp @@ -0,0 +1,168 @@ +#include <godot_cpp/core/error_macros.hpp> +#include <godot_cpp/variant/vector2.hpp> +#include <godot_cpp/variant/string.hpp> + +namespace godot { + +Vector2::operator String() const { + return String::num(x, 5) + ", " + String::num(y, 5); +} + +real_t Vector2::angle() const { + return Math::atan2(y, x); +} + +real_t Vector2::length() const { + return Math::sqrt(x * x + y * y); +} + +real_t Vector2::length_squared() const { + return x * x + y * y; +} + +void Vector2::normalize() { + real_t l = x * x + y * y; + if (l != 0) { + l = Math::sqrt(l); + x /= l; + y /= l; + } +} + +Vector2 Vector2::normalized() const { + Vector2 v = *this; + v.normalize(); + return v; +} + +bool Vector2::is_normalized() const { + // use length_squared() instead of length() to avoid sqrt(), makes it more stringent. + return Math::is_equal_approx(length_squared(), 1.0, UNIT_EPSILON); +} + +real_t Vector2::distance_to(const Vector2 &p_vector2) const { + return Math::sqrt((x - p_vector2.x) * (x - p_vector2.x) + (y - p_vector2.y) * (y - p_vector2.y)); +} + +real_t Vector2::distance_squared_to(const Vector2 &p_vector2) const { + return (x - p_vector2.x) * (x - p_vector2.x) + (y - p_vector2.y) * (y - p_vector2.y); +} + +real_t Vector2::angle_to(const Vector2 &p_vector2) const { + return Math::atan2(cross(p_vector2), dot(p_vector2)); +} + +real_t Vector2::angle_to_point(const Vector2 &p_vector2) const { + return Math::atan2(y - p_vector2.y, x - p_vector2.x); +} + +real_t Vector2::dot(const Vector2 &p_other) const { + return x * p_other.x + y * p_other.y; +} + +real_t Vector2::cross(const Vector2 &p_other) const { + return x * p_other.y - y * p_other.x; +} + +Vector2 Vector2::sign() const { + return Vector2(Math::sign(x), Math::sign(y)); +} + +Vector2 Vector2::floor() const { + return Vector2(Math::floor(x), Math::floor(y)); +} + +Vector2 Vector2::ceil() const { + return Vector2(Math::ceil(x), Math::ceil(y)); +} + +Vector2 Vector2::round() const { + return Vector2(Math::round(x), Math::round(y)); +} + +Vector2 Vector2::rotated(real_t p_by) const { + real_t sine = Math::sin(p_by); + real_t cosi = Math::cos(p_by); + return Vector2( + x * cosi - y * sine, + x * sine + y * cosi); +} + +Vector2 Vector2::posmod(const real_t p_mod) const { + return Vector2(Math::fposmod(x, p_mod), Math::fposmod(y, p_mod)); +} + +Vector2 Vector2::posmodv(const Vector2 &p_modv) const { + return Vector2(Math::fposmod(x, p_modv.x), Math::fposmod(y, p_modv.y)); +} + +Vector2 Vector2::project(const Vector2 &p_to) const { + return p_to * (dot(p_to) / p_to.length_squared()); +} + +Vector2 Vector2::snapped(const Vector2 &p_step) const { + return Vector2( + Math::snapped(x, p_step.x), + Math::snapped(y, p_step.y)); +} + +Vector2 Vector2::clamped(real_t p_len) const { + real_t l = length(); + Vector2 v = *this; + if (l > 0 && p_len < l) { + v /= l; + v *= p_len; + } + + return v; +} + +Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_weight) const { + Vector2 p0 = p_pre_a; + Vector2 p1 = *this; + Vector2 p2 = p_b; + Vector2 p3 = p_post_b; + + real_t t = p_weight; + real_t t2 = t * t; + real_t t3 = t2 * t; + + Vector2 out; + out = 0.5 * ((p1 * 2.0) + + (-p0 + p2) * t + + (2.0 * p0 - 5.0 * p1 + 4 * p2 - p3) * t2 + + (-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3); + return out; +} + +Vector2 Vector2::move_toward(const Vector2 &p_to, const real_t p_delta) const { + Vector2 v = *this; + Vector2 vd = p_to - v; + real_t len = vd.length(); + return len <= p_delta || len < CMP_EPSILON ? p_to : v + vd / len * p_delta; +} + +// slide returns the component of the vector along the given plane, specified by its normal vector. +Vector2 Vector2::slide(const Vector2 &p_normal) const { +#ifdef MATH_CHECKS + ERR_FAIL_COND_V(!p_normal.is_normalized(), Vector2()); +#endif + return *this - p_normal * this->dot(p_normal); +} + +Vector2 Vector2::bounce(const Vector2 &p_normal) const { + return -reflect(p_normal); +} + +Vector2 Vector2::reflect(const Vector2 &p_normal) const { +#ifdef MATH_CHECKS + ERR_FAIL_COND_V(!p_normal.is_normalized(), Vector2()); +#endif + return 2.0 * p_normal * this->dot(p_normal) - *this; +} + +bool Vector2::is_equal_approx(const Vector2 &p_v) const { + return Math::is_equal_approx(x, p_v.x) && Math::is_equal_approx(y, p_v.y); +} + +} // namespace godot |