From 29b354d754ce8c17b249b5d032dd31736744f5a3 Mon Sep 17 00:00:00 2001 From: Luca Carniato Date: Tue, 8 Aug 2023 17:34:42 +0200 Subject: [PATCH] Add vector class Add rotate in Entities.hpp for now More rows and columns are generated in one unit test (most of the values are invalid) --- libs/MeshKernel/CMakeLists.txt | 1 + .../include/MeshKernel/BoundingBox.hpp | 4 +- .../include/MeshKernel/Entities.hpp | 18 ++++++ libs/MeshKernel/include/MeshKernel/Vector.hpp | 64 +++++++++++++++++++ .../CurvilinearGridCreateUniform.cpp | 36 +++++------ libs/MeshKernelApi/tests/src/ApiTest.cpp | 4 +- 6 files changed, 102 insertions(+), 25 deletions(-) create mode 100644 libs/MeshKernel/include/MeshKernel/Vector.hpp diff --git a/libs/MeshKernel/CMakeLists.txt b/libs/MeshKernel/CMakeLists.txt index a8d8b6143..da9cffc5e 100644 --- a/libs/MeshKernel/CMakeLists.txt +++ b/libs/MeshKernel/CMakeLists.txt @@ -114,6 +114,7 @@ set( ${DOMAIN_INC_DIR}/Splines.hpp ${DOMAIN_INC_DIR}/TriangulationInterpolation.hpp ${DOMAIN_INC_DIR}/TriangulationWrapper.hpp + ${DOMAIN_INC_DIR}/Vector.hpp ) set( diff --git a/libs/MeshKernel/include/MeshKernel/BoundingBox.hpp b/libs/MeshKernel/include/MeshKernel/BoundingBox.hpp index cccb8d3cb..cd08e0798 100644 --- a/libs/MeshKernel/include/MeshKernel/BoundingBox.hpp +++ b/libs/MeshKernel/include/MeshKernel/BoundingBox.hpp @@ -98,11 +98,11 @@ namespace meshkernel /// @brief Returns the lower left corner of the bounding box /// @return The lower left corner of the bounding box - auto lowerLeft() const { return m_lowerLeft; } + [[nodiscard]] auto& lowerLeft() const { return m_lowerLeft; } /// @brief Returns the upper right corner /// @return The upper right corner of the bounding box - auto upperRight() const { return m_upperRight; } + [[nodiscard]] auto& upperRight() const { return m_upperRight; } /// @brief Returns the mass centre /// @return The upper right corner of the bounding box diff --git a/libs/MeshKernel/include/MeshKernel/Entities.hpp b/libs/MeshKernel/include/MeshKernel/Entities.hpp index fe3f26c29..47bb2d0ca 100644 --- a/libs/MeshKernel/include/MeshKernel/Entities.hpp +++ b/libs/MeshKernel/include/MeshKernel/Entities.hpp @@ -214,6 +214,24 @@ namespace meshkernel /// @returns \f$ p1.x = p2.x \wedge p1.y = p2.y)\f$ bool operator==(const Point& p1, const Point& p2); + /// @brief Rotate a point around a reference + /// @param[in] point The point to rotate + /// @param[in] angle The rotation angle + /// @param[in] reference The reference point where rotation should be performed + /// @returns The rotated point + static Point Rotate(const Point& point, const double angle, const Point& reference) + { + const auto translatedPoint = point - reference; + + const auto angleInRad = angle * constants::conversion::degToRad; + const auto cosineAngle = std::cos(angleInRad); + const auto sinAngle = std::sin(angleInRad); + Point result(translatedPoint.x * cosineAngle - translatedPoint.y * sinAngle, + translatedPoint.x * sinAngle + translatedPoint.y * cosineAngle); + + return result + reference; + } + /// @brief Describes an edge with two indices using Edge = std::pair; diff --git a/libs/MeshKernel/include/MeshKernel/Vector.hpp b/libs/MeshKernel/include/MeshKernel/Vector.hpp new file mode 100644 index 000000000..ff2732a11 --- /dev/null +++ b/libs/MeshKernel/include/MeshKernel/Vector.hpp @@ -0,0 +1,64 @@ +//---- GPL --------------------------------------------------------------------- +// +// Copyright (C) Stichting Deltares, 2011-2021. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation version 3. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// contact: delft3d.support@deltares.nl +// Stichting Deltares +// P.O. Box 177 +// 2600 MH Delft, The Netherlands +// +// All indications and logos of, and references to, "Delft3D" and "Deltares" +// are registered trademarks of Stichting Deltares, and remain the property of +// Stichting Deltares. All rights reserved. +// +//------------------------------------------------------------------------------ + +#pragma once + +namespace meshkernel +{ + /// @brief A class defining a vector + class Vector + { + public: + /// @brief Class constructor + /// + /// @param[in] x The x coordinate of the vector + /// @param[in] y The y coordinate of the vector + Vector(const double x, const double y) + : m_x(x), + m_y(y) + { + } + + /// @brief Gets the x coordinate of the vector + /// @returns x The x coordinate of the vector + [[nodiscard]] double x() const + { + return m_x; + } + + /// @brief Gets the y coordinate of the vector + /// @returns x The y coordinate of the vector + [[nodiscard]] double y() const + { + return m_y; + } + + private: + double m_x; ///< The x coordinate of the vector + double m_y ///< The y coordinate of the vector + }; +} // namespace meshkernel diff --git a/libs/MeshKernel/src/CurvilinearGrid/CurvilinearGridCreateUniform.cpp b/libs/MeshKernel/src/CurvilinearGrid/CurvilinearGridCreateUniform.cpp index 72eb1a3c2..842eab1fa 100644 --- a/libs/MeshKernel/src/CurvilinearGrid/CurvilinearGridCreateUniform.cpp +++ b/libs/MeshKernel/src/CurvilinearGrid/CurvilinearGridCreateUniform.cpp @@ -273,32 +273,26 @@ CurvilinearGrid CurvilinearGridCreateUniform::Compute(const double angle, } // Compute the bounding box - auto boundingBox = polygons->GetBoundingBox(polygonIndex); - boundingBox.ExtendBoundingBox(0.2); + const auto boundingBox = polygons->GetBoundingBox(polygonIndex); + const auto referencePoint = boundingBox.MassCentre(); - // Compute the bounding box properties - const auto boundingBoxLowerLeft = boundingBox.lowerLeft(); - const auto boundingBoxUpperRight = boundingBox.upperRight(); - const auto massCentre = boundingBox.MassCentre(); + // Compute the max size + const auto maxSize = std::max(boundingBox.Width(), boundingBox.Height()); - // Compute the number of rows and columns - const int numColumns = std::max(static_cast(std::ceil(std::abs(boundingBoxUpperRight.x - boundingBoxLowerLeft.x) / blockSizeX)), 1); - const int numRows = ComputeNumRows(boundingBoxLowerLeft.y, boundingBoxUpperRight.y, blockSizeY, m_projection); + // Compute the lower left and upper right corners + const Point lowerLeft(referencePoint.x - maxSize, referencePoint.y - maxSize); + const Point upperRight(referencePoint.x + maxSize, referencePoint.y + maxSize); - // Translate the point to the origin - const double translatedX = boundingBoxLowerLeft.x - massCentre.x; - const double translatedY = boundingBoxLowerLeft.y - massCentre.y; + // Compute the number of rows and columns + const int numColumns = std::max(static_cast(std::ceil(std::abs(upperRight.x - lowerLeft.x) / blockSizeX)), 1); + const int numRows = ComputeNumRows(lowerLeft.y, upperRight.y, blockSizeY, m_projection); - // Rotate the point - const auto angleInRad = angle * constants::conversion::degToRad; - const auto cosineAngle = std::cos(angleInRad); - const auto sinAngle = std::sin(angleInRad); - const double rotatedX = translatedX * cosineAngle - translatedY * sinAngle; - const double rotatedY = translatedX * sinAngle + translatedY * cosineAngle; + // Rotated the lower left corner + const auto lowerLeftMergedRotated = Rotate(lowerLeft, angle, referencePoint); - // Translate the rotated point back to the original position - const double originX = rotatedX + massCentre.x; - const double originY = rotatedY + massCentre.y; + // Set the origin + const double originX = lowerLeftMergedRotated.x; + const double originY = lowerLeftMergedRotated.y; CurvilinearGrid curvilinearGrid; switch (m_projection) diff --git a/libs/MeshKernelApi/tests/src/ApiTest.cpp b/libs/MeshKernelApi/tests/src/ApiTest.cpp index d781648dd..6659d34f3 100644 --- a/libs/MeshKernelApi/tests/src/ApiTest.cpp +++ b/libs/MeshKernelApi/tests/src/ApiTest.cpp @@ -3364,8 +3364,8 @@ TEST(CurvilinearGrid, MakeUniformn_OnSphericalCoordinatesWithpolygon_ShouldMakeC ASSERT_EQ(meshkernelapi::MeshKernelApiErrors::Success, errorCode); // Assert - ASSERT_EQ(44, curvilinearGridResults.num_m); - ASSERT_EQ(43, curvilinearGridResults.num_n); + ASSERT_EQ(125, curvilinearGridResults.num_m); + ASSERT_EQ(61, curvilinearGridResults.num_n); } TEST(CurvilinearGrid, MakeUniformOnDefinedExtension_OnSphericalCoordinates_ShouldMakeCurvilinearGrid)