From 4b8e92712665832c7b9e689bcb0362b080db0326 Mon Sep 17 00:00:00 2001 From: Ryo Suzuki Date: Sat, 22 Jun 2024 20:23:13 +0900 Subject: [PATCH] =?UTF-8?q?[=E5=85=B1=E9=80=9A]=20=E3=83=99=E3=82=AF?= =?UTF-8?q?=E3=83=88=E3=83=AB=E3=81=AE=E6=AD=A3=E8=A6=8F=E5=8C=96=E4=BB=95?= =?UTF-8?q?=E6=A7=98=E5=A4=89=E6=9B=B4=20#1237=20#1152?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Siv3D/include/Siv3D/Vector2D.hpp | 6 ++++ Siv3D/include/Siv3D/Vector3D.hpp | 6 ++++ Siv3D/include/Siv3D/Vector4D.hpp | 6 ++++ Siv3D/include/Siv3D/detail/Vector2D.ipp | 39 +++++++++++++++++++++-- Siv3D/include/Siv3D/detail/Vector3D.ipp | 40 ++++++++++++++++++++++-- Siv3D/include/Siv3D/detail/Vector4D.ipp | 41 +++++++++++++++++++++++-- 6 files changed, 132 insertions(+), 6 deletions(-) diff --git a/Siv3D/include/Siv3D/Vector2D.hpp b/Siv3D/include/Siv3D/Vector2D.hpp index a2f320422..d74e09eff 100644 --- a/Siv3D/include/Siv3D/Vector2D.hpp +++ b/Siv3D/include/Siv3D/Vector2D.hpp @@ -322,6 +322,12 @@ namespace s3d /// @return *this Vector2D& normalize() noexcept; + /// @brief 正規化した(大きさを 1 にした)ベクトルを返します。ゼロベクトルの場合は valueIfZero を返します。 + /// @param valueIfZero ゼロベクトルの場合に返すベクトル + /// @return 正規化した(大きさを 1 にした)ベクトル、または valueIfZero + [[nodiscard]] + Vector2D normalized_or(Vector2D valueIfZero) const noexcept; + [[nodiscard]] Vector2D rotated(value_type angle) const noexcept; diff --git a/Siv3D/include/Siv3D/Vector3D.hpp b/Siv3D/include/Siv3D/Vector3D.hpp index 862145edc..dec8e1dfb 100644 --- a/Siv3D/include/Siv3D/Vector3D.hpp +++ b/Siv3D/include/Siv3D/Vector3D.hpp @@ -325,6 +325,12 @@ namespace s3d /// @return *this Vector3D& normalize() noexcept; + /// @brief 正規化した(大きさを 1 にした)ベクトルを返します。ゼロベクトルの場合は valueIfZero を返します。 + /// @param valueIfZero ゼロベクトルの場合に返すベクトル + /// @return 正規化した(大きさを 1 にした)ベクトル、または valueIfZero + [[nodiscard]] + Vector3D normalized_or(Vector3D valueIfZero) const noexcept; + [[nodiscard]] constexpr Vector3D getMidpoint(Vector3D other) const noexcept; diff --git a/Siv3D/include/Siv3D/Vector4D.hpp b/Siv3D/include/Siv3D/Vector4D.hpp index b7e5faa8a..7a2e1e360 100644 --- a/Siv3D/include/Siv3D/Vector4D.hpp +++ b/Siv3D/include/Siv3D/Vector4D.hpp @@ -261,6 +261,12 @@ namespace s3d Vector4D& normalize() noexcept; + /// @brief 正規化した(大きさを 1 にした)ベクトルを返します。ゼロベクトルの場合は valueIfZero を返します。 + /// @param valueIfZero ゼロベクトルの場合に返すベクトル + /// @return 正規化した(大きさを 1 にした)ベクトル、または valueIfZero + [[nodiscard]] + Vector4D normalized_or(Vector4D valueIfZero) const noexcept; + [[nodiscard]] constexpr Vector4D getMidpoint(Vector4D other) const noexcept; diff --git a/Siv3D/include/Siv3D/detail/Vector2D.ipp b/Siv3D/include/Siv3D/detail/Vector2D.ipp index 0ee3c5123..75bfc9e16 100644 --- a/Siv3D/include/Siv3D/detail/Vector2D.ipp +++ b/Siv3D/include/Siv3D/detail/Vector2D.ipp @@ -435,13 +435,48 @@ namespace s3d template inline Vector2D Vector2D::normalized() const noexcept { - return (*this * invLength()); + const value_type lenSq = lengthSq(); + + if (lenSq == 0) + { + return *this; + } + + const value_type invLen = (static_cast(1.0) / std::sqrt(lenSq)); + + return{ (x * invLen), (y * invLen) }; } template inline Vector2D& Vector2D::normalize() noexcept { - return (*this *= invLength()); + const value_type lenSq = lengthSq(); + + if (lenSq == 0) + { + x = y = 0; + } + else + { + const value_type invLen = (static_cast(1.0) / std::sqrt(lenSq)); + x *= invLen; + y *= invLen; + } + + return *this; + } + + template + inline Vector2D Vector2D::normalized_or(const Vector2D valueIfZero) const noexcept + { + const value_type lenSq = lengthSq(); + + if (lenSq == 0) + { + return valueIfZero; + } + + return (*this * (static_cast(1.0) / std::sqrt(lenSq))); } template diff --git a/Siv3D/include/Siv3D/detail/Vector3D.ipp b/Siv3D/include/Siv3D/detail/Vector3D.ipp index ab66fdfcd..4efab1310 100644 --- a/Siv3D/include/Siv3D/detail/Vector3D.ipp +++ b/Siv3D/include/Siv3D/detail/Vector3D.ipp @@ -447,13 +447,49 @@ namespace s3d template inline Vector3D Vector3D::normalized() const noexcept { - return (*this * invLength()); + const value_type lenSq = lengthSq(); + + if (lenSq == 0) + { + return *this; + } + + const value_type invLen = (static_cast(1.0) / std::sqrt(lenSq)); + + return{ (x * invLen), (y * invLen), (z * invLen) }; } template inline Vector3D& Vector3D::normalize() noexcept { - return (*this *= invLength()); + const value_type lenSq = lengthSq(); + + if (lenSq == 0) + { + x = y = z = 0; + } + else + { + const value_type invLen = (static_cast(1.0) / std::sqrt(lenSq)); + x *= invLen; + y *= invLen; + z *= invLen; + } + + return *this; + } + + template + inline Vector3D Vector3D::normalized_or(const Vector3D valueIfZero) const noexcept + { + const value_type lenSq = lengthSq(); + + if (lenSq == 0) + { + return valueIfZero; + } + + return (*this * (static_cast(1.0) / std::sqrt(lenSq))); } template diff --git a/Siv3D/include/Siv3D/detail/Vector4D.ipp b/Siv3D/include/Siv3D/detail/Vector4D.ipp index cb84ef4a3..191e0e44c 100644 --- a/Siv3D/include/Siv3D/detail/Vector4D.ipp +++ b/Siv3D/include/Siv3D/detail/Vector4D.ipp @@ -498,13 +498,50 @@ namespace s3d template inline Vector4D Vector4D::normalized() const noexcept { - return (*this * invLength()); + const value_type lenSq = lengthSq(); + + if (lenSq == 0) + { + return *this; + } + + const value_type invLen = (static_cast(1.0) / std::sqrt(lenSq)); + + return{ (x * invLen), (y * invLen), (z * invLen), (w * invLen) }; } template inline Vector4D& Vector4D::normalize() noexcept { - return (*this *= invLength()); + const value_type lenSq = lengthSq(); + + if (lenSq == 0) + { + x = y = z = w = 0; + } + else + { + const value_type invLen = (static_cast(1.0) / std::sqrt(lenSq)); + x *= invLen; + y *= invLen; + z *= invLen; + w *= invLen; + } + + return *this; + } + + template + inline Vector4D Vector4D::normalized_or(const Vector4D valueIfZero) const noexcept + { + const value_type lenSq = lengthSq(); + + if (lenSq == 0) + { + return valueIfZero; + } + + return (*this * (static_cast(1.0) / std::sqrt(lenSq))); } template