/* * Critical_points.h * Created on: Jan 27, 2015 * This file is part of the Gudhi Library. The Gudhi library * (Geometric Understanding in Higher Dimensions) is a generic C++ * library for computational topology. * * Author(s): David Salinas * * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France) * * 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, either version 3 of the License, or * (at your option) any later version. * * 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 . * */ #ifndef CRITICAL_POINTS_H_ #define CRITICAL_POINTS_H_ #include #include "utils/Edge_contractor.h" /** * Iteratively tries to anticollapse smallest edge non added so far. * If its link is contractible then no topological change and else possible topological change. * * todo do a sparsification with some parameter eps while growing */ template class Critical_points{ private: SkBlComplex filled_complex_; const SkBlComplex& input_complex_; double max_length_; std::ostream& stream_; public: typedef typename SkBlComplex::Vertex_handle Vertex_handle; typedef typename SkBlComplex::Edge_handle Edge_handle; typedef typename std::pair Edge; /** * @brief check all pair of points with length smaller than max_length */ Critical_points(const SkBlComplex& input_complex,std::ostream& stream,double max_length): input_complex_(input_complex),max_length_(max_length),stream_(stream) { std::deque edges; auto vertices = input_complex.vertex_range(); for(auto p = vertices.begin(); p!= vertices.end(); ++p){ filled_complex_.add_vertex(input_complex.point(*p)); for (auto q = p; ++q != vertices.end(); /**/) if (squared_eucl_distance(input_complex.point(*p),input_complex.point(*q)) < max_length_*max_length_) edges.emplace_back(*p,*q); } std::sort(edges.begin(),edges.end(), [&](Edge e1,Edge e2){ return squared_edge_length(e1) < squared_edge_length(e2); }); anti_collapse_edges(edges); } private: double squared_eucl_distance(const Point& p1,const Point& p2) const{ return Geometry_trait::Squared_distance_d()(p1,p2); } void anti_collapse_edges(const std::deque& edges){ unsigned pos = 0; for(Edge e : edges){ std::cout<<"edge "< not //1 -> yes //2 -> maybe int is_link_reducible(Edge_handle e){ auto link = filled_complex_.link(e); if(link.empty()) return 0; Edge_contractor contractor(link,link.num_vertices()-1); if(link.num_connected_components()>1) return 0; //one than more CC -> not contractible if (link.num_vertices()==1) return 1; //reduced to one point -> contractible else return 2; //we dont know } double squared_edge_length(Edge_handle e) const{ return squared_eucl_distance(input_complex_.point(input_complex_.first_vertex(e)),input_complex_.point(input_complex_.second_vertex(e))); } double squared_edge_length(Edge e) const{ return squared_eucl_distance(input_complex_.point(e.first),input_complex_.point(e.second)); } }; #endif /* CRITICAL_POINTS_H_ */