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) 2005 INRIA Sophia-Antipolis (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org) // // $URL: https://github.com/CGAL/cgal/blob/v6.1/Principal_component_analysis_LGPL/include/CGAL/centroid.h $ // $Id: include/CGAL/centroid.h b26b07a1242 $ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Sylvain Pion #ifndef CGAL_CENTROID_H #define CGAL_CENTROID_H #include #include #include #include #include #include #include #include #include #include #include // Functions to compute the centroid of N points. // Works in 2D and 3D. // TODO : Note : more numerically stable variants could be implemented as well. // TODO : Specify a traits class concept ? // TODO : Grep for "barycenter" and "centroid" in CGAL to check existing usages. // TODO : Add barycentric_coordinates() (to the kernel, this time). namespace CGAL { namespace internal { //:::::::::: 2D Objects ::::::::::::::::::: // computes the centroid of a 2D point set // takes an iterator range over K::Point_2 template < typename InputIterator, typename K > typename K::Point_2 centroid(InputIterator begin, InputIterator end, const K&, const typename K::Point_2*, CGAL::Dimension_tag<0>) { typedef typename K::Vector_2 Vector; typedef typename K::FT FT; CGAL_precondition(begin != end); Vector v = NULL_VECTOR; unsigned int nb_pts = 0; while(begin != end) { v = v + (*begin++ - ORIGIN); nb_pts++; } return ORIGIN + v / (FT)nb_pts; }// end centroid of a 2D point set // computes the centroid of a 2D segment set // takes an iterator range over K::Segment_2 // centroid for 2D segment set with 0D tag template < typename InputIterator, typename K > typename K::Point_2 centroid(InputIterator begin, InputIterator end, const K& k, const typename K::Segment_2*, CGAL::Dimension_tag<0> tag) { typedef typename K::Point_2 Point; typedef typename K::Segment_2 Segment; CGAL_precondition(begin != end); std::list points; for(InputIterator it = begin; it != end; it++) { const Segment& s = *it; points.push_back(s[0]); points.push_back(s[1]); } return centroid(points.begin(),points.end(),k,(Point*)nullptr,tag); }// end centroid for 2D segment set with 0D tag // centroid for 2D segment set with 1D tag template < typename InputIterator, typename K > typename K::Point_2 centroid(InputIterator begin, InputIterator end, const K& , const typename K::Segment_2*, CGAL::Dimension_tag<1>) { typedef typename K::FT FT; typedef typename K::Vector_2 Vector; typedef typename K::Point_2 Point; typedef typename K::Segment_2 Segment; CGAL_precondition(begin != end); Vector v = NULL_VECTOR; FT sum_lengths = 0; for(InputIterator it = begin; it != end; it++) { const Segment& s = *it; FT length = CGAL::approximate_sqrt(CGAL::abs(s.squared_length())); Point c = K().construct_midpoint_2_object()(s[0],s[1]); v = v + length * (c - ORIGIN); sum_lengths += length; } CGAL_assertion(sum_lengths != 0.0); return ORIGIN + v / sum_lengths; } // end centroid of a 2D segment set with 1D tag // computes the centroid of a 2D triangle set // takes an iterator range over K::Triangle_2 // centroid for 2D triangle set with 0D tag template < typename InputIterator, typename K > typename K::Point_2 centroid(InputIterator begin, InputIterator end, const K& k, const typename K::Triangle_2*, CGAL::Dimension_tag<0> tag) { typedef typename K::Triangle_2 Triangle; typedef typename K::Point_2 Point; CGAL_precondition(begin != end); std::list points; for(InputIterator it = begin; it != end; it++) { const Triangle& triangle = *it; points.push_back(triangle[0]); points.push_back(triangle[1]); points.push_back(triangle[2]); } return centroid(points.begin(),points.end(),k,(Point*)nullptr,tag); } // end centroid of a 2D triangle set with 0D tag // centroid for 2D triangle set with 1D tag template < typename InputIterator, typename K > typename K::Point_2 centroid(InputIterator begin, InputIterator end, const K& k, const typename K::Triangle_2*, CGAL::Dimension_tag<1> tag) { typedef typename K::Triangle_2 Triangle; typedef typename K::Segment_2 Segment; CGAL_precondition(begin != end); std::list segments; for(InputIterator it = begin; it != end; it++) { const Triangle& triangle = *it; segments.push_back(triangle[0],triangle[1]); segments.push_back(triangle[1],triangle[2]); segments.push_back(triangle[2],triangle[0]); } return centroid(segments.begin(),segments.end(),k,(Segment*)nullptr,tag); } // end centroid of a 2D triangle set with 1D tag // centroid for 2D triangle set with 2D tag template < typename InputIterator, typename K > typename K::Point_2 centroid(InputIterator begin, InputIterator end, const K& , const typename K::Triangle_2*, CGAL::Dimension_tag<2>) { typedef typename K::FT FT; typedef typename K::Vector_2 Vector; typedef typename K::Point_2 Point; typedef typename K::Triangle_2 Triangle; CGAL_precondition(begin != end); Vector v = NULL_VECTOR; FT sum_areas = 0; for(InputIterator it = begin; it != end; it++) { const Triangle& triangle = *it; FT unsigned_area = CGAL::abs(triangle.area()); Point c = K().construct_centroid_2_object()(triangle[0],triangle[1],triangle[2]); v = v + unsigned_area * (c - ORIGIN); sum_areas += unsigned_area; } CGAL_assertion(sum_areas != 0.0); return ORIGIN + v / sum_areas; } // end centroid of a 2D triangle set with 2D tag // computes the centroid of a 2D circle set // takes an iterator range over K::Circle_2 // centroid for 2D circle set with 1D tag template < typename InputIterator, typename K > typename K::Point_2 centroid(InputIterator begin, InputIterator end, const K& , const typename K::Circle_2*, CGAL::Dimension_tag<1>) { typedef typename K::FT FT; typedef typename K::Vector_2 Vector; typedef typename K::Point_2 Point; typedef typename K::Circle_2 Circle; CGAL_precondition(begin != end); Vector v = NULL_VECTOR; FT sum_lengths = 0; for(InputIterator it = begin; it != end; it++) { const Circle& s = *it; FT radius = CGAL::approximate_sqrt(s.squared_radius()); Point c = s.center(); v = v + radius * (c - ORIGIN); sum_lengths += radius; } CGAL_assertion(sum_lengths != 0.0); return ORIGIN + v / sum_lengths; } // end centroid of a 2D circle set with 1D tag // centroid for 2D circle set with 2D tag template < typename InputIterator, typename K > typename K::Point_2 centroid(InputIterator begin, InputIterator end, const K& , const typename K::Circle_2*, CGAL::Dimension_tag<2>) { typedef typename K::FT FT; typedef typename K::Vector_2 Vector; typedef typename K::Point_2 Point; typedef typename K::Circle_2 Circle; CGAL_precondition(begin != end); Vector v = NULL_VECTOR; FT sum_areas = 0; for(InputIterator it = begin; it != end; it++) { const Circle& s = *it; FT sq_radius = s.squared_radius(); Point c = s.center(); v = v + sq_radius * (c - ORIGIN); sum_areas += sq_radius; } CGAL_assertion(sum_areas != 0.0); return ORIGIN + v / sum_areas; } // end centroid of a 2D circle set with 2D tag // computes the centroid of a 2D rectangle set // takes an iterator range over K::Iso_Rectangle_2 // centroid for 2D rectangle set with 0D tag template < typename InputIterator, typename K > typename K::Point_2 centroid(InputIterator begin, InputIterator end, const K& k, const typename K::Iso_rectangle_2*, CGAL::Dimension_tag<0> tag) { typedef typename K::Iso_rectangle_2 Iso_rectangle; typedef typename K::Point_2 Point; CGAL_precondition(begin != end); std::list points; for(InputIterator it = begin; it != end; it++) { const Iso_rectangle& r = *it; points.push_back(r[0]); points.push_back(r[1]); points.push_back(r[2]); points.push_back(r[3]); } return centroid(points.begin(),points.end(),k,(Point*)nullptr,tag); } // end centroid of a 2D rectangle set with 0D tag // centroid for 2D rectangle set with 1D tag template < typename InputIterator, typename K > typename K::Point_2 centroid(InputIterator begin, InputIterator end, const K& k, const typename K::Iso_rectangle_2*, CGAL::Dimension_tag<1> tag) { typedef typename K::Iso_rectangle_2 Iso_rectangle; typedef typename K::Segment_2 Segment; CGAL_precondition(begin != end); std::list segments; for(InputIterator it = begin; it != end; it++) { const Iso_rectangle& r = *it; segments.push_back(r[0],r[1]); segments.push_back(r[1],r[2]); segments.push_back(r[2],r[3]); segments.push_back(r[3],r[0]); } return centroid(segments.begin(),segments.end(),k,(Segment*)nullptr,tag); } // end centroid of a 2D rectangle set with 1D tag // centroid for 2D rectangle set with 2D tag template < typename InputIterator, typename K > typename K::Point_2 centroid(InputIterator begin, InputIterator end, const K& , const typename K::Iso_rectangle_2*, CGAL::Dimension_tag<2>) { typedef typename K::FT FT; typedef typename K::Vector_2 Vector; typedef typename K::Point_2 Point; typedef typename K::Iso_rectangle_2 Iso_rectangle; CGAL_precondition(begin != end); Vector v = NULL_VECTOR; FT sum_areas = 0; for(InputIterator it = begin; it != end; it++) { const Iso_rectangle& r = *it; FT unsigned_area = CGAL::abs(r.area()); Point c = K().construct_centroid_2_object()(r[0],r[1],r[2],r[3]); v = v + unsigned_area * (c - ORIGIN); sum_areas += unsigned_area; } CGAL_assertion(sum_areas != 0.0); return ORIGIN + v / sum_areas; } // end centroid of a 2D rectangle set with 2D tag // computes the centroid of a 3D point set // takes an iterator range over K::Point_3 // centroid for 3D point set with 0D tag template < typename InputIterator, typename K > typename K::Point_3 centroid(InputIterator begin, InputIterator end, const K& k, const typename K::Point_3*, CGAL::Dimension_tag<0>) { typedef typename K::Vector_3 Vector; typedef typename K::FT FT; CGAL_precondition(begin != end); Vector v = NULL_VECTOR; unsigned int nb_pts = 0; while (begin != end) { v = v + k.construct_vector_3_object()(ORIGIN, *begin++); nb_pts++; } return ORIGIN + v / (FT)nb_pts; }// end centroid of a 3D point set with 0D tag // centroid for 3D segment set with 1D tag template < typename InputIterator, typename K > typename K::Point_3 centroid(InputIterator begin, InputIterator end, const K& , const typename K::Segment_3*, CGAL::Dimension_tag<1>) { typedef typename K::FT FT; typedef typename K::Vector_3 Vector; typedef typename K::Point_3 Point; typedef typename K::Segment_3 Segment; CGAL_precondition(begin != end); Vector v = NULL_VECTOR; FT sum_lengths = 0; for(InputIterator it = begin; it != end; it++) { const Segment& s = *it; FT length = CGAL::approximate_sqrt(s.squared_length()); Point c = CGAL::midpoint(s.source(),s.target()); // Point c = K().construct_midpoint_3_object()(s[0],s[1]); //Point c = Point((s[0][0] + s[1][0])/2.0, (s[0][1] + s[1][1])/2.0, (s[0][2] + s[1][2])/2.0); v = v + length * (c - ORIGIN); sum_lengths += length; } CGAL_assertion(sum_lengths != 0.0); return ORIGIN + v / sum_lengths; } // end centroid of a 3D segment set with 1D tag // computes the centroid of a 3D triangle set // takes an iterator range over K::Triangle_3 // centroid for 3D triangle set with 0D tag template < typename InputIterator, typename K > typename K::Point_3 centroid(InputIterator begin, InputIterator end, const K& k, const typename K::Triangle_3*, CGAL::Dimension_tag<0> tag) { typedef typename K::Triangle_3 Triangle; typedef typename K::Point_3 Point; CGAL_precondition(begin != end); std::list points; for(InputIterator it = begin; it != end; it++) { const Triangle& triangle = *it; points.push_back(triangle[0]); points.push_back(triangle[1]); points.push_back(triangle[2]); } return centroid(points.begin(),points.end(),k,(Point*)nullptr,tag); } // end centroid of a 3D triangle set with 0D tag // centroid for 3D triangle set with 1D tag template < typename InputIterator, typename K > typename K::Point_3 centroid(InputIterator begin, InputIterator end, const K& k, const typename K::Triangle_3*, CGAL::Dimension_tag<1> tag) { typedef typename K::Triangle_3 Triangle; typedef typename K::Segment_3 Segment; CGAL_precondition(begin != end); std::list segments; for(InputIterator it = begin; it != end; it++) { const Triangle& triangle = *it; segments.push_back(triangle[0],triangle[1]); segments.push_back(triangle[1],triangle[2]); segments.push_back(triangle[2],triangle[0]); } return centroid(segments.begin(),segments.end(),k,(Segment*)nullptr,tag); } // end centroid of a 3D triangle set with 1D tag // centroid for 3D triangle set with 2D tag template < typename InputIterator, typename K > typename K::Point_3 centroid(InputIterator begin, InputIterator end, const K& , const typename K::Triangle_3*, CGAL::Dimension_tag<2>) { typedef typename K::FT FT; typedef typename K::Vector_3 Vector; typedef typename K::Point_3 Point; typedef typename K::Triangle_3 Triangle; CGAL_precondition(begin != end); Vector v = NULL_VECTOR; FT sum_areas = 0; for(InputIterator it = begin; it != end; it++) { const Triangle& triangle = *it; FT unsigned_area = CGAL::approximate_sqrt(triangle.squared_area()); Point c = K().construct_centroid_3_object()(triangle[0],triangle[1],triangle[2]); v = v + unsigned_area * (c - ORIGIN); sum_areas += unsigned_area; } CGAL_assertion(sum_areas != 0.0); return ORIGIN + v / sum_areas; } // end centroid of a 3D triangle set with 2D tag // computes the centroid of a 3D sphere set // takes an iterator range over K::Sphere_3 // centroid for 3D sphere set with 2D tag template < typename InputIterator, typename K > typename K::Point_3 centroid(InputIterator begin, InputIterator end, const K& , const typename K::Sphere_3*, CGAL::Dimension_tag<2>) { typedef typename K::FT FT; typedef typename K::Vector_3 Vector; typedef typename K::Point_3 Point; typedef typename K::Sphere_3 Sphere; CGAL_precondition(begin != end); Vector v = NULL_VECTOR; FT sum_areas = 0; for(InputIterator it = begin; it != end; it++) { const Sphere& sphere = *it; FT unsigned_area = sphere.squared_radius(); Point c = sphere.center(); v = v + unsigned_area * (c - ORIGIN); sum_areas += unsigned_area; } CGAL_assertion(sum_areas != 0.0); return ORIGIN + v / sum_areas; } // end centroid of a 3D sphere set with 2D tag // centroid for 3D sphere set with 3D tag template < typename InputIterator, typename K > typename K::Point_3 centroid(InputIterator begin, InputIterator end, const K& , const typename K::Sphere_3*, CGAL::Dimension_tag<3>) { typedef typename K::FT FT; typedef typename K::Vector_3 Vector; typedef typename K::Point_3 Point; typedef typename K::Sphere_3 Sphere; CGAL_precondition(begin != end); Vector v = NULL_VECTOR; FT sum_volumes = 0; for(InputIterator it = begin; it != end; it++) { const Sphere& sphere = *it; FT unsigned_volume = sphere.squared_radius() * CGAL::approximate_sqrt(sphere.squared_radius()); Point c = sphere.center(); v = v + unsigned_volume * (c - ORIGIN); sum_volumes += unsigned_volume; } CGAL_assertion(sum_volumes != 0.0); return ORIGIN + v / sum_volumes; } // end centroid of a 3D sphere set with 3 tag // computes the centroid of a 3D cuboid set // takes an iterator range over K::Iso_cuboid_3 // centroid for 3D cuboid set with 0D tag template < typename InputIterator, typename K > typename K::Point_3 centroid(InputIterator begin, InputIterator end, const K& k, const typename K::Iso_cuboid_3*, CGAL::Dimension_tag<0> tag) { typedef typename K::Iso_cuboid_3 Iso_cuboid; typedef typename K::Point_3 Point; CGAL_precondition(begin != end); std::list points; for(InputIterator it = begin; it != end; it++) { const Iso_cuboid& cuboid = *it; points.push_back(cuboid[0]); points.push_back(cuboid[1]); points.push_back(cuboid[2]); points.push_back(cuboid[3]); points.push_back(cuboid[4]); points.push_back(cuboid[5]); points.push_back(cuboid[6]); points.push_back(cuboid[7]); } return centroid(points.begin(),points.end(),k,(Point*)nullptr,tag); } // end centroid of a 3D cuboid set with 0D tag // centroid for 3D cuboid set with 1D tag template < typename InputIterator, typename K > typename K::Point_3 centroid(InputIterator begin, InputIterator end, const K& k, const typename K::Iso_cuboid_3*, CGAL::Dimension_tag<1> tag) { typedef typename K::Iso_cuboid_3 Iso_cuboid; typedef typename K::Segment_3 Segment; CGAL_precondition(begin != end); std::list segments; for(InputIterator it = begin; it != end; it++) { const Iso_cuboid& cuboid = *it; segments.push_back(cuboid[0],cuboid[1]); segments.push_back(cuboid[1],cuboid[2]); segments.push_back(cuboid[2],cuboid[3]); segments.push_back(cuboid[3],cuboid[0]); segments.push_back(cuboid[0],cuboid[5]); segments.push_back(cuboid[5],cuboid[4]); segments.push_back(cuboid[4],cuboid[3]); segments.push_back(cuboid[1],cuboid[6]); segments.push_back(cuboid[6],cuboid[7]); segments.push_back(cuboid[7],cuboid[2]); segments.push_back(cuboid[4],cuboid[7]); segments.push_back(cuboid[5],cuboid[6]); } return centroid(segments.begin(),segments.end(),k,(Segment*)nullptr,tag); } // end centroid of a 3D cuboid set with 1D tag // centroid for 3D cuboid set with 2D tag template < typename InputIterator, typename K > typename K::Point_3 centroid(InputIterator begin, InputIterator end, const K& , const typename K::Iso_cuboid_3*, CGAL::Dimension_tag<2>) { typedef typename K::FT FT; typedef typename K::Vector_3 Vector; typedef typename K::Point_3 Point; typedef typename K::Iso_cuboid_3 Iso_cuboid; CGAL_precondition(begin != end); Vector v = NULL_VECTOR; FT sum_areas = 0; for(InputIterator it = begin; it != end; it++) { const Iso_cuboid& cuboid = *it; FT unsigned_area = 2 * ((cuboid.xmax()-cuboid.xmin())*(cuboid.ymax()-cuboid.ymin()) + (cuboid.xmax()-cuboid.xmin())*(cuboid.zmax()-cuboid.zmin()) + (cuboid.ymax()-cuboid.ymin())*(cuboid.zmax()-cuboid.zmin())); Point c = K().construct_midpoint_3_object()(cuboid[0],cuboid[7]); v = v + unsigned_area * (c - ORIGIN); sum_areas += unsigned_area; } CGAL_assertion(sum_areas != 0.0); return ORIGIN + v / sum_areas; } // end centroid of a 3D cuboid set with 2D tag // centroid for 3D cuboid set with 3D tag template < typename InputIterator, typename K > typename K::Point_3 centroid(InputIterator begin, InputIterator end, const K& , const typename K::Iso_cuboid_3*, CGAL::Dimension_tag<3>) { typedef typename K::FT FT; typedef typename K::Vector_3 Vector; typedef typename K::Point_3 Point; typedef typename K::Iso_cuboid_3 Iso_cuboid; CGAL_precondition(begin != end); Vector v = NULL_VECTOR; FT sum_volumes = 0; for(InputIterator it = begin; it != end; it++) { const Iso_cuboid& cuboid = *it; FT unsigned_volume = cuboid.volume(); Point c = K().construct_midpoint_3_object()(cuboid[0],cuboid[7]); v = v + unsigned_volume * (c - ORIGIN); sum_volumes += unsigned_volume; } CGAL_assertion(sum_volumes != 0.0); return ORIGIN + v / sum_volumes; } // end centroid of a 3D cuboid set with 3D tag // centroid for 3D Tetrahedron set with 3D tag template < typename InputIterator, typename K > typename K::Point_3 centroid(InputIterator begin, InputIterator end, const K& , const typename K::Tetrahedron_3*, CGAL::Dimension_tag<3>) { typedef typename K::FT FT; typedef typename K::Vector_3 Vector; typedef typename K::Point_3 Point; typedef typename K::Tetrahedron_3 Tetrahedron; CGAL_precondition(begin != end); Vector v = NULL_VECTOR; FT sum_volumes = (FT)0.0; for(InputIterator it = begin; it != end; it++) { const Tetrahedron& tetrahedron = *it; FT unsigned_volume = CGAL::abs(tetrahedron.volume()); Point c = K().construct_centroid_3_object()(tetrahedron[0],tetrahedron[1],tetrahedron[2],tetrahedron[3]); v = v + unsigned_volume * (c - ORIGIN); sum_volumes += unsigned_volume; } CGAL_assertion(sum_volumes != (FT)0.0); return ORIGIN + v / sum_volumes; } // end centroid of a 3D Tetrahedron set with 3D tag } // namespace internal // We have 4 documented overloads of centroid(): // centroid(begin, end) // centroid(begin, end, dim_tag) // centroid(begin, end, kernel) // centroid(begin, end, kernel, dim_tag) // One issue is that it is difficult to separate the 2 overloads with 3 arguments. // So we have to resort to an internal internal dispatcher hack. // ( Note : Dynamic_dimension_tag is not yet supported, but shouldn't be too hard. ) // computes the centroid of a set of kernel objects // takes an iterator range over kernel objects namespace internal { template < typename InputIterator, typename K, typename Dim_tag > struct Dispatch_centroid_3 { typedef typename Access::Point::value_type, K>::type>::type result_type; result_type operator()(InputIterator begin, InputIterator end, const K& k, Dim_tag tag) const { typedef typename std::iterator_traits::value_type Value_type; return centroid(begin, end, k,(Value_type*) nullptr, tag); } }; } // namespace internal template < typename InputIterator, typename K> typename internal::Dispatch_centroid_3< std::enable_if_t::value,InputIterator>, K,Dynamic_dimension_tag>::result_type centroid(InputIterator begin, InputIterator end, const K& k, Dynamic_dimension_tag tag) { return internal::Dispatch_centroid_3()(begin,end,k,tag); } template < typename InputIterator, typename K, int d > typename internal::Dispatch_centroid_3< std::enable_if_t::value,InputIterator>, K,Dimension_tag >::result_type centroid(InputIterator begin, InputIterator end, const K& k, Dimension_tag tag) { return internal::Dispatch_centroid_3 >()(begin,end,k,tag); } namespace internal { // computes the centroid of a set of kernel objects // takes an iterator range over kernel objects, and a feature dimension tag. template < typename InputIterator, typename Kernel_or_Dim > struct Dispatch_centroid { typedef Kernel_or_Dim K; typedef typename Access::Point::value_type, K>::type >::type result_type; result_type operator()(InputIterator begin, InputIterator end, const K& k) const { typedef typename std::iterator_traits::value_type Value_type; return CGAL::centroid(begin, end, k, typename Feature_dimension::type()); } }; // this one takes an iterator range over kernel objects, and a dimension tag, // and uses Kernel_traits<> to find out its kernel. template < typename InputIterator, int dim > struct Dispatch_centroid < InputIterator, Dimension_tag > { typedef typename Kernel_traits::value_type>::Kernel K; typedef typename Access::Point::value_type, K >::type >::type result_type; result_type operator()(InputIterator begin, InputIterator end, Dimension_tag tag) const { typedef typename std::iterator_traits::value_type Point; typedef typename Kernel_traits::Kernel K; return CGAL::centroid(begin, end, K(), tag); } }; // Same as above for dynamic dimension template < typename InputIterator > struct Dispatch_centroid { typedef typename Kernel_traits::value_type>::Kernel K; typedef typename Access::Point::value_type, K >::type >::type result_type; result_type operator()(InputIterator begin, InputIterator end, Dynamic_dimension_tag tag) const { typedef typename std::iterator_traits::value_type Point; typedef typename Kernel_traits::Kernel K; return CGAL::centroid(begin, end, K(), tag); } }; } // namespace internal // The 3 argument overload calls the internal dispatcher. template < typename InputIterator, typename Kernel_or_dim > inline typename internal::Dispatch_centroid< std::enable_if_t::value,InputIterator>, Kernel_or_dim>::result_type centroid(InputIterator begin, InputIterator end, const Kernel_or_dim& k_or_d) { internal::Dispatch_centroid dispatch_centroid; return dispatch_centroid(begin, end, k_or_d); } namespace internal { template::value> class Centroid_2args_return_type_helper{}; template class Centroid_2args_return_type_helper{ typedef typename std::iterator_traits::value_type val; typedef typename Kernel_traits::Kernel K; public: typedef typename Access::Point::type>::type type; }; } // this one takes an iterator range over kernel objects // and uses Kernel_traits<> to find out its kernel, and Feature_dimension for the dimension tag. template < typename InputIterator > inline typename internal::Centroid_2args_return_type_helper::type centroid(InputIterator begin, InputIterator end) { typedef typename std::iterator_traits::value_type Point; typedef typename Kernel_traits::Kernel K; return CGAL::centroid(begin, end, K()); } } //namespace CGAL #endif