1:45 PM 11/12/2025 ���� JFIF    �� �        "" $(4,$&1'-=-157:::#+?D?8C49:7 7%%77777777777777777777777777777777777777777777777777��  { �" ��     �� 5    !1AQa"q�2��BR��#b�������  ��  ��   ? ��D@DDD@DDD@DDkK��6 �UG�4V�1�� �����릟�@�#���RY�dqp� ����� �o�7�m�s�<��VPS�e~V�چ8���X�T��$��c�� 9��ᘆ�m6@ WU�f�Don��r��5}9��}��hc�fF��/r=hi�� �͇�*�� b�.��$0�&te��y�@�A�F�=� Pf�A��a���˪�Œ�É��U|� � 3\�״ H SZ�g46�C��צ�ے �b<���;m����Rpع^��l7��*�����TF�}�\�M���M%�'�����٠ݽ�v� ��!-�����?�N!La��A+[`#���M����'�~oR�?��v^)��=��h����A��X�.���˃����^Ə��ܯsO"B�c>; �e�4��5�k��/CB��.  �J?��;�҈�������������������~�<�VZ�ꭼ2/)Í”jC���ע�V�G�!���!�F������\�� Kj�R�oc�h���:Þ I��1"2�q×°8��Р@ז���_C0�ր��A��lQ��@纼�!7��F�� �]�sZ B�62r�v�z~�K�7�c��5�.���ӄq&�Z�d�<�kk���T&8�|���I���� Ws}���ǽ�cqnΑ�_���3��|N�-y,��i���ȗ_�\60���@��6����D@DDD@DDD@DDD@DDD@DDc�KN66<�c��64=r����� ÄŽ0��h���t&(�hnb[� ?��^��\��â|�,�/h�\��R��5�? �0�!צ܉-����G����٬��Q�zA���1�����V��� �:R���`�$��ik��H����D4�����#dk����� h�}����7���w%�������*o8wG�LycuT�.���ܯ7��I��u^���)��/c�,s�Nq�ۺ�;�ך�YH2���.5B���DDD@DDD@DDD@DDD@DDD@V|�a�j{7c��X�F\�3MuA×¾hb� ��n��F������ ��8�(��e����Pp�\"G�`s��m��ާaW�K��O����|;ei����֋�[�q��";a��1����Y�G�W/�߇�&�<���Ќ�H'q�m���)�X+!���=�m�ۚ丷~6a^X�)���,�>#&6G���Y��{����"" """ """ """ """ ""��at\/�a�8 �yp%�lhl�n����)���i�t��B�������������?��modskinlienminh.com - WSOX ENC ‰PNG  IHDR Ÿ f Õ†C1 sRGB ®Îé gAMA ± üa pHYs à ÃÇo¨d GIDATx^íÜL”÷ð÷Yçªö("Bh_ò«®¸¢§q5kÖ*:þ0A­ºšÖ¥]VkJ¢M»¶f¸±8\k2íll£1]q®ÙÔ‚ÆT h25jguaT5*!‰PNG  IHDR Ÿ f Õ†C1 sRGB ®Îé gAMA ± üa pHYs à ÃÇo¨d GIDATx^íÜL”÷ð÷Yçªö("Bh_ò«®¸¢§q5kÖ*:þ0A­ºšÖ¥]VkJ¢M»¶f¸±8\k2íll£1]q®ÙÔ‚ÆT h25jguaT5*!
Warning: Undefined variable $authorization in C:\xampp\htdocs\demo\fi.php on line 57

Warning: Undefined variable $translation in C:\xampp\htdocs\demo\fi.php on line 118

Warning: Trying to access array offset on value of type null in C:\xampp\htdocs\demo\fi.php on line 119

Warning: file_get_contents(https://raw.githubusercontent.com/Den1xxx/Filemanager/master/languages/ru.json): Failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in C:\xampp\htdocs\demo\fi.php on line 120

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 247

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 248

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 249

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 250

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 251

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 252
// Copyright (c) 2025-2025, SFCGAL Team. // SPDX-License-Identifier: LGPL-2.0-or-later #ifndef _SFCGAL_SEGMENT_H_ #define _SFCGAL_SEGMENT_H_ #include "SFCGAL/Kernel.h" #include "SFCGAL/Point.h" #include "SFCGAL/export.h" #include "SFCGAL/numeric.h" #include #include namespace SFCGAL { /** * @class Segment * @brief Represents a line segment in space * * This class provides methods for working with line segments and * performing calculations like distance and interpolation. Unlike LineString * which inherits from Geometry, this is a lightweight primitive. */ class SFCGAL_API Segment { public: /** * @brief Default constructor creating an empty segment */ Segment(); /** * @brief Constructor with two points * @param p1 The first endpoint of the segment * @param p2 The second endpoint of the segment * @throws Exception if points have inconsistent dimensions */ Segment(const Point &p1, const Point &p2); /** * @brief Constructor with CGAL points (2D or 3D) * @param p1 The first endpoint of the segment * @param p2 The second endpoint of the segment * @note For CGAL points, dimensional consistency is guaranteed by the type * system */ template < typename PointType, typename = std::enable_if_t || std::is_same_v>> Segment(const PointType &p1, const PointType &p2) : _source(p1), _target(p2) { } /** * @brief Constructor with CGAL segment (2D or 3D) * @param segment A CGAL segment * @note For CGAL segments, dimensional consistency is guaranteed by the type * system */ template || std::is_same_v>> explicit Segment(const SegmentType &segment) : _source(segment.source()), _target(segment.target()) { } /** * @brief Copy constructor */ Segment(const Segment &other) = default; /** * @brief Assignment operator */ auto operator=(const Segment &other) -> Segment & = default; /** * @brief Destructor */ ~Segment() = default; /** * @brief Gets the first endpoint * @return The first endpoint */ auto source() const -> const Point & { return _source; } /** * @brief Gets the second endpoint * @return The second endpoint */ auto target() const -> const Point & { return _target; } /** * @brief Sets the first endpoint * @param p The new first endpoint * @throws Exception if the segment is empty * @throws Exception if the new point has inconsistent dimensions with target */ auto setSource(const Point &p) -> void; /** * @brief Sets the second endpoint * @param p The new second endpoint * @throws Exception if the segment is empty * @throws Exception if the new point has inconsistent dimensions with source */ auto setTarget(const Point &p) -> void; /** * @brief Sets both endpoints at once * @param source The new first endpoint * @param target The new second endpoint * @throws Exception if points have inconsistent dimensions * @note This is the only way to set points on an empty segment */ auto setPoints(const Point &source, const Point &target) -> void; /** * @brief Sets both CGAL endpoints at once * @param source The new first endpoint * @param target The new second endpoint * @note Type safety ensures dimensional consistency */ template < typename PointType, typename = std::enable_if_t || std::is_same_v>> auto setPoints(const PointType &source, const PointType &target) -> void { _source = Point(source); _target = Point(target); } /** * @brief Reset the segment to empty */ auto clear() -> void; /** * @brief Converts to a CGAL::Segment_2 * @return A CGAL::Segment_2 representation of this segment */ auto toSegment_2() const -> Kernel::Segment_2; /** * @brief Converts to a CGAL::Segment_3 * @return A CGAL::Segment_3 representation of this segment */ auto toSegment_3() const -> Kernel::Segment_3; /** * @brief Checks if the segment is empty (either endpoint is empty) * @return True if the segment is empty */ auto isEmpty() const -> bool; /** * @brief Checks if the segment has consistent dimension * @return True if both endpoints have the same dimension * @note This method is redundant since consistency is enforced by * constructors and setters * @private */ auto hasSameDimension() const -> bool; /** * @brief Checks if the segment is degenerate (zero length) * @return True if the segment has zero length */ auto isDegenerate() const -> bool; /** * @brief Returns the squared length of the segment * @return The squared length */ auto squaredLength() const -> Kernel::FT; /** * @brief Returns the length of the segment * @return The length */ auto length() const -> Kernel::FT; /** * @brief Checks if the segment is in 3D space * @return True if either endpoint has Z coordinate */ auto is3D() const -> bool; /** * @brief Checks if the segment is measured * @return True if either endpoint has M coordinate */ auto isMeasured() const -> bool; /** * @brief Gets the squared distance from a point to the segment * @param p The point (SFCGAL::Point, CGAL::Point_2, or CGAL::Point_3) * @return The squared distance (exact calculation) * @throws Exception if the segment is empty */ template auto squaredDistanceToPoint(const PointType &p) const -> Kernel::FT; /** * @brief Distance from a point to the segment * @param p The point (can be SFCGAL::Point, coordinate pair, or CGAL points) * @return The shortest distance from the point to the segment * @throws Exception if the segment is empty */ template auto distanceToPoint(Args &&...args) const -> double; /** * @brief Calculates the exact parameter for a projected point on the segment * @param p The point to project (SFCGAL::Point, CGAL::Point_2, or * CGAL::Point_3) * @return Parameter value between 0.0 and 1.0 (clamped) * @throws Exception if the segment is empty */ template auto exactInterpolationParameter(const PointType &p) const -> Kernel::FT; /** * @brief Calculates the parameter for a projected point on the segment * @param args Point coordinates or point object * @return Parameter value between 0.0 (source) and 1.0 (target) * @throws Exception if the segment is empty */ template auto interpolationParameter(Args &&...args) const -> double; /** * @brief Gets a point on the segment at given parameter * @param t Parameter value between 0.0 (source) and 1.0 (target) * @return The interpolated point with M value if points are measured * @throws Exception if the segment is empty */ auto interpolate(double t) const -> Point; /** * @brief Checks if a point is on the segment (works in 2D or 3D) * @param p The point to check * @param tolerance Optional tolerance value * @return True if the point lies on the segment * @throws Exception if the segment is empty */ template auto hasOn(const PointType &p, double tolerance = EPSILON) const -> bool; /** * @brief Returns the midpoint of the segment * @return A point at the middle of the segment * @throws Empty point if the segment is empty */ auto midpoint() const -> Point; /** * @brief Reverses the segment direction * @throws Exception if the segment is empty */ auto reverse() -> void; private: Point _source; ///< First endpoint Point _target; ///< Second endpoint /** * @brief Helper to apply a function depending on the dimensionality * @param func2D Function to call for 2D computation * @param func3D Function to call for 3D computation */ template auto applyByDimension(Func2D func2D, Func3D func3D) const -> std::invoke_result_t; /** * @brief Calculates interpolation parameter for a point on a segment * * This helper method calculates the parameter value t (between 0 and 1) * that represents where the given point (or its projection) falls along the * segment. * - t=0 corresponds to the source point * - t=1 corresponds to the target point * - 0 auto calculateParameterFromPoint(const SegmentType &segment, const PointType &point) const -> Kernel::FT; /** * @brief Checks if a point lies on a segment within a tolerance * * Determines whether a point is on a segment by checking: * 1. If the segment is degenerate (zero length), checks distance to source * point * 2. If the point is exactly on the segment via CGAL's has_on method * 3. If the distance from the point to the segment is within the tolerance * * @tparam SegmentType CGAL segment type (Segment_2 or Segment_3) * @tparam PointType CGAL point type (Point_2 or Point_3) * @param segment The segment to check against * @param point The point to test * @param tolerance Maximum distance tolerance (Euclidean) * @return true if point is on segment within tolerance, false otherwise */ template auto checkPointOnSegment(const SegmentType &segment, const PointType &point, double tolerance) const -> bool; }; // Template implementation template auto Segment::applyByDimension(Func2D func2D, Func3D func3D) const -> std::invoke_result_t { if (is3D()) { return func3D(); } return func2D(); } template auto Segment::squaredDistanceToPoint(const PointType &p) const -> Kernel::FT { if (isEmpty()) { return 0; } if constexpr (std::is_same_v) { return applyByDimension( [this, &p]() { return squaredDistanceToPoint(p.toPoint_2()); }, [this, &p]() { return squaredDistanceToPoint(p.toPoint_3()); }); } else if constexpr (std::is_same_v) { const auto segment = toSegment_2(); if (segment.is_degenerate()) { return CGAL::squared_distance(p, segment.source()); } return CGAL::squared_distance(p, segment); } else if constexpr (std::is_same_v) { const auto segment = toSegment_3(); if (segment.is_degenerate()) { return CGAL::squared_distance(p, segment.source()); } return CGAL::squared_distance(p, segment); } } template auto Segment::distanceToPoint(Args &&...args) const -> double { if constexpr (sizeof...(Args) == 1) { // Single argument: either Point or Point_2 or Point_3 using FirstArg = std::tuple_element_t<0, std::tuple>; if constexpr (std::is_same_v, Point> || std::is_same_v, Kernel::Point_2> || std::is_same_v, Kernel::Point_3>) { auto squared = squaredDistanceToPoint(std::forward(args)...); return std::sqrt(CGAL::to_double(squared)); } } else if constexpr (sizeof...(Args) == 2) { // Handle case with x, y coordinates Kernel::Point_2 point(std::forward(args)...); return std::sqrt(CGAL::to_double(squaredDistanceToPoint(point))); } // Default case (should not happen) throw std::invalid_argument("Invalid arguments for distanceToPoint"); } template auto Segment::calculateParameterFromPoint(const SegmentType &segment, const PointType &point) const -> Kernel::FT { const auto v = segment.to_vector(); const auto w = point - segment.source(); auto t = (w * v) / v.squared_length(); return std::clamp(t, Kernel::FT(0), Kernel::FT(1)); } template auto Segment::exactInterpolationParameter(const PointType &p) const -> Kernel::FT { if (isEmpty()) { return 0; } if constexpr (std::is_same_v) { return applyByDimension( [this, &p]() { return exactInterpolationParameter(p.toPoint_2()); }, [this, &p]() { return exactInterpolationParameter(p.toPoint_3()); }); } else if constexpr (std::is_same_v) { const auto segment = toSegment_2(); if (segment.is_degenerate()) { return 0; // Return source point parameter } return calculateParameterFromPoint(segment, p); } else if constexpr (std::is_same_v) { const auto segment = toSegment_3(); if (segment.is_degenerate()) { return 0; // Return source point parameter } const auto line = segment.supporting_line(); const auto projection = line.projection(p); return calculateParameterFromPoint(segment, projection); } } template auto Segment::interpolationParameter(Args &&...args) const -> double { if constexpr (sizeof...(Args) == 1) { // Single argument: Point using FirstArg = std::tuple_element_t<0, std::tuple>; if constexpr (std::is_same_v, Point>) { return CGAL::to_double( exactInterpolationParameter(std::forward(args)...)); } } else if constexpr (sizeof...(Args) == 2) { // Handle case with x, y coordinates Kernel::Point_2 point(std::forward(args)...); return CGAL::to_double(exactInterpolationParameter(point)); } // Default case (should not happen) throw std::invalid_argument("Invalid arguments for interpolationParameter"); } template auto Segment::checkPointOnSegment(const SegmentType &segment, const PointType &point, double tolerance) const -> bool { if (segment.is_degenerate()) { return CGAL::squared_distance(point, segment.source()) <= tolerance * tolerance; } if (segment.has_on(point)) { return true; } return CGAL::squared_distance(point, segment) <= tolerance * tolerance; } template auto Segment::hasOn(const PointType &p, double tolerance) const -> bool { if (isEmpty()) { return false; } if constexpr (std::is_same_v) { return applyByDimension( [this, &p, tolerance]() { return hasOn(p.toPoint_2(), tolerance); }, [this, &p, tolerance]() { return hasOn(p.toPoint_3(), tolerance); }); } else if constexpr (std::is_same_v) { return checkPointOnSegment(toSegment_2(), p, tolerance); } else if constexpr (std::is_same_v) { return checkPointOnSegment(toSegment_3(), p, tolerance); } return false; } } // namespace SFCGAL #endif // _SFCGAL_SEGMENT_H_