// Copyright (c) 2005 INRIA Sophia-Antipolis (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org). // You can redistribute it and/or modify it under the terms of the GNU // General Public License as published by the Free Software Foundation, // either version 3 of the License, or (at your option) any later version. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $URL$ // $Id$ // SPDX-License-Identifier: GPL-3.0+ // // // Author(s) : Abdelkrim Mebarki #ifndef CGAL_TRIANGULAR_FIELD_2_H_ #define CGAL_TRIANGULAR_FIELD_2_H_ #include #include #include #include #include #include #include #include #include #include #include #include namespace CGAL { template class Triangular_field_2 { public: typedef Triangular_field_2 Vector_field_2; typedef StreamLinesTraits_2 Geom_traits; typedef typename StreamLinesTraits_2::FT FT; typedef typename StreamLinesTraits_2::Point_2 Point_2; typedef typename StreamLinesTraits_2::Vector_2 Vector_2; protected: typedef CGAL::Triangulation_vertex_base_2 Vb; typedef CGAL::Triangulation_face_base_with_info_2 Fb; typedef CGAL::Triangulation_data_structure_2 TDS; typedef CGAL::Delaunay_triangulation_2 D_Ttr; typedef typename D_Ttr::Vertex_handle Vertex_handle; typedef typename TDS::Face_handle Face_handle; public: typedef typename D_Ttr::Vertex_iterator Vertex_iterator; D_Ttr m_D_Ttr; protected: Vector_2 get_vector_field(const Point_2 & p) const; FT get_density_field(const Point_2 & p) const; template void fill(PointInputIterator pBegin, PointInputIterator pEnd, VectorInputIterator vBegin) { std::cout << "reading file...\n"; while(pBegin != pEnd) { Point_2 p; Vector_2 v; p = (*pBegin); v = (*vBegin); m_D_Ttr.insert(p); field_map[p] = v; if (m_D_Ttr.number_of_vertices() == 1) { maxx = minx = p.x(); maxy = miny = p.y(); } if(p.x()maxx) { maxx = p.x(); } if(p.y()>maxy) { maxy = p.y(); } ++pBegin; ++vBegin; } std::cout << "number of samples " << m_D_Ttr.number_of_vertices() << "\n"; } public: template Triangular_field_2(PointInputIterator pBegin, PointInputIterator pEnd, VectorInputIterator vBegin) { fill(pBegin, pEnd, vBegin); } inline typename Geom_traits::Iso_rectangle_2 bbox() const; std::pair get_field(const Point_2 & p) const { CGAL_assertion(is_in_domain(p)); Vector_2 v = get_vector_field(p); FT density = get_density_field(p); return std::make_pair(v, density); } bool is_in_domain(const Point_2 & p) const; FT get_integration_step(const Point_2 &) const; FT get_integration_step() const; protected: FT minx; FT miny; FT maxx; FT maxy; protected: mutable std::map field_map; FT distance(const Point_2 & p, const Point_2 & q) { return sqrt( CGAL::squared_distance(p, q) ); } }; template inline typename Triangular_field_2::Geom_traits::Iso_rectangle_2 Triangular_field_2::bbox() const { return typename Geom_traits::Iso_rectangle_2(minx, miny, maxx, maxy); } template bool Triangular_field_2::is_in_domain(const Point_2 & p) const { Face_handle f = m_D_Ttr.locate(p); return !m_D_Ttr.is_infinite(f); } template typename Triangular_field_2::Vector_2 Triangular_field_2::get_vector_field(const Point_2 & p) const { Face_handle m_Face_handle = m_D_Ttr.locate(p); CGAL_assertion(is_in_domain(p)); Vertex_handle v0 = m_Face_handle->vertex(0); Vertex_handle v1 = m_Face_handle->vertex(1); Vertex_handle v2 = m_Face_handle->vertex(2); const Point_2 & p0 = v0->point(); const Point_2 & p1 = v1->point(); const Point_2 & p2 = v2->point(); FT s0,s1,s2,s; std::vector vec; vec.push_back(p0); vec.push_back(p1); vec.push_back(p2); s = polygon_area_2(vec.begin(), vec.end(), m_D_Ttr.geom_traits()); vec.clear(); vec.push_back(p); vec.push_back(p1); vec.push_back(p2); s0 = polygon_area_2(vec.begin(), vec.end(), m_D_Ttr.geom_traits()); vec.clear(); vec.push_back(p0); vec.push_back(p); vec.push_back(p2); s1 = polygon_area_2(vec.begin(), vec.end(), m_D_Ttr.geom_traits()); vec.clear(); vec.push_back(p0); vec.push_back(p1); vec.push_back(p); s2 = polygon_area_2(vec.begin(), vec.end(), m_D_Ttr.geom_traits()); vec.clear(); s0 = s0 / s; s1 = s1 / s; s2 = s2 / s; Vector_2 v_0 = field_map[p0]; Vector_2 v_1 = field_map[p1]; Vector_2 v_2 = field_map[p2]; FT x = ((v_0.x()*s0)+(v_1.x()*s1)+(v_2.x()*s2)); FT y = ((v_0.y()*s0)+(v_1.y()*s1)+(v_2.y()*s2)); FT normal = sqrt((x)*(x) + (y)*(y)); if (normal != 0) { x = x / normal; y = y / normal; } Vector_2 v = Vector_2(x, y); return v; } template typename Triangular_field_2::FT Triangular_field_2::get_density_field(const Point_2 & p) const { return p.x(); } template typename Triangular_field_2::FT Triangular_field_2::get_integration_step(const Point_2 &) const { return 1.0; } template typename Triangular_field_2::FT Triangular_field_2::get_integration_step() const { return 1.0; } } //namespace CGAL #endif