In the following code, a delaunay triangulation is made from an N dimensional array named points. Every element of this array has an index associated with it. For every vertex of the triangulation the nearest vertex is found correctly (without using the libraray: CGAL/Triangulation_vertex_base...). Now, I want to retrieve the index of each neighbor point with ->info(), but the way I've implemented that leads to error! How can I do that?
#include <vector>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
using namespace std();
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef CGAL::Triangulation_vertex_base_with_info_2<unsigned int, Kernel> Vb;
typedef CGAL::Triangulation_data_structure_2<Vb> Tds;
typedef CGAL::Delaunay_triangulation_2<Kernel, Tds> Triangulation;
typedef Triangulation::Edge_iterator Edge_iterator;
typedef Triangulation::Point Point;
typedef Triangulation::Vertex_handle Vertex_handle;
typedef Triangulation::Vertex_circulator Vertex_circulator;
typedef Kernel::Point_2 Point_2;
typedef std::vector<std::pair<Point_2, unsigned> > Vector;
const int N = 16;
int main(){
Vector points;
points.reserve(N);
.... {Some part of code which assignes values to dir[N][2]}
for (int i = 0; i < N; i++)
points.push_back(make_pair(Point_2(dir[i][0], dir[i][1]), i));\\ I want each point to have an index
Triangulation T;
T.insert(points.begin(), points.end());
cout << T.number_of_vertices() <<endl;
for(int i = 0; i < N; i++){
Vertex_handle handle = T.nearest_vertex(points[i]);
cout<<"incidents: \n" <<endl;
cout << handle->point() <<endl<<endl;
Vertex_circulator circulator = T.incident_vertices(handle), done(circulator);
do
{
if( !T.is_infinite ( circulator))
cout << circulator->point() << endl;
cout << circulator->point()->info()<<endl;
} while(++circulator != done);
}
return 0;}
edit: It seems that the origin of the error is primarily because of using the following kernel: typedef CGAL::Delaunay_triangulation_2 Triangulation;
error: no matching function for call to CGAL::Delaunay_triangulation_2 > >::nearest_vertex(std::pair, unsigned int>&)’
edit 2: when I print the output in two different lines, weired number(96) appears:
The code:
cout<<circulator->point()<<endl;
cout<<circulator->info()<<endl;
output(total number of points, 4):
3.26675 0.733887
2
96
2.02307 0.718587
1
2.33861 1.68862
3
when I print the information in one line, the number 96 disappears;
cout<<circulator->point()<<"\t"<<circulator->info()<<endl;
3.26675 0.733887 2
2.02307 0.718587 1
2.33861 1.68862 3
Related
I have created a sample example for the intersection of two circles.
In this example I am able to get the bound faces and the source and target points.
I have manually plotted the source and target points. Refer snapshot for the same two intersecting circles:
I want to find out whether the edges between the source and target points is a line segment, arc or a circle.
I tried to find this in the 2D arrangement documentation but couldn't find it.
Below is the code snippet :
#include <CGAL/Cartesian.h>
#include <CGAL/Exact_rational.h>
#include <CGAL/Arr_circle_segment_traits_2.h>
#include <CGAL/Arrangement_2.h>
typedef CGAL::Cartesian<CGAL::Exact_rational> Kernel;
typedef Kernel::Circle_2 Circle_2;
typedef CGAL::Arr_circle_segment_traits_2<Kernel> Traits_2;
typedef Traits_2::CoordNT CoordNT;
typedef Traits_2::Point_2 Point_2;
typedef Traits_2::Curve_2 Curve_2;
typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
int main()
{
// Create a circle centered at (0,0) with radius 8.
Kernel::Point_2 c1 = Kernel::Point_2(0, 0);
CGAL::Exact_rational sqr_r1 = CGAL::Exact_rational(64); // = 8*^2
Circle_2 circ1 = Circle_2(c1, sqr_r1, CGAL::CLOCKWISE);
Curve_2 cv1 = Curve_2(circ1);
// Create a circle centered at (10,0) with radius 8.
Kernel::Point_2 c2 = Kernel::Point_2(10, 0);
CGAL::Exact_rational sqr_r2 = CGAL::Exact_rational(64); // = 8*^2
Circle_2 circ2 = Circle_2(c2, sqr_r2, CGAL::CLOCKWISE);
Curve_2 cv2 = Curve_2(circ2);
Arrangement_2 arr;
insert(arr, cv1);
insert(arr, cv2);
for (auto fit = arr.faces_begin(); fit != arr.faces_end(); ++fit)
{
if (fit->is_unbounded())
std::cout << "Unbounded face.\n";
else {
Arrangement_2::Ccb_halfedge_circulator curr, start;
start = curr = fit->outer_ccb();
do {
std::cout << " source --> " << curr->source()->point() << "\n";
std::cout << " target --> " << curr->target()->point() << "\n";
++curr;
} while (curr != start);
std::cout << std::endl;
}
}
return 0;
}
I want to copy a mesh with the function copy_face_graph(source, target). But the target mesh is different (it has same number of vertices and faces, but the coordinates and the order are totally different).
The code:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <iostream>
#include <fstream>
#include <CGAL/boost/graph/copy_face_graph.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef CGAL::Surface_mesh<Kernel::Point_3> Mesh;
namespace PMP = CGAL::Polygon_mesh_processing;
int main(int argc, char* argv[]) {
const char* filename1 = (argc > 1) ? argv[1] : "data/blobby.off";
std::cout << ".off loaded" << std::endl;
std::ifstream input(filename1);
Mesh mesh_orig;
if (!input || !(input >> mesh_orig))
{
std::cerr << "First mesh is not a valid off file." << std::endl;
return 1;
}
input.close();
// ========================================================
Mesh mesh_copy;
CGAL::copy_face_graph(mesh_orig, mesh_copy);
// ========================================================
std::ofstream mesh_cpy("CPY_ANYLYZE/mesh_copy.off");
mesh_cpy << mesh_copy;
mesh_cpy.close();
return 0;
}
Dose anyone knows how to get a complete same mesh from the original mesh? Do I need add the named parameters, or maybe using another function?
Thanks a lot
Except if you intend to write some code working with different data structures, you can use the copy constructor from the Surface_mesh class, Mesh mesh_copy(mesh_orig). copy_face_graph does not do a raw copy because it works also if the input and output are of different types. However the output should be the same up to the order of the simplices.
I am using the Point_set_2 data structure in order to find k nearest neighbors of a query point, I want to retrieve the index of neighbors; I used the following code, but it->info() produces errors!
I have also seen this post, but for me the priority is using Point_set_2 method:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
#include <CGAL/Point_set_2.h>
#include <vector>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Triangulation_vertex_base_with_info_2<unsigned, K> Vb;
typedef CGAL::Triangulation_data_structure_2<Vb> Tds;
typedef CGAL::Delaunay_triangulation_2<K, Tds> Delaunay;
//typedef Delaunay::Point Point;
typedef CGAL::Point_set_2<K,Tds>::Edge_iterator Edge_iterator;
typedef CGAL::Point_set_2<K,Tds>::Vertex_handle Vertex_handle;
typedef K::Point_2 Point_2;
CGAL::Point_set_2<K,Tds> PSet;
int main()
{
std::vector< std::pair<Point_2,unsigned> > points;
points.push_back( std::make_pair(Point_2(0,0),0) );
points.push_back( std::make_pair(Point_2(1,0),1) );
points.push_back( std::make_pair(Point_2(0,1),2) );
points.push_back( std::make_pair(Point_2(14,4),3) );
points.push_back( std::make_pair(Point_2(2,2),4) );
points.push_back( std::make_pair(Point_2(-4,0),5) );
PSet.insert(points.begin(),points.end());
// init
Point_2 actual(30,45,10);
// nearest neighbor ...
Vertex_handle v = PSet.nearest_neighbor(actual);
std::cout << "Nearest neighbor:" << v->point() << "\n";
// k nearest neighbors ...
std::vector<Vertex_handle> L;
std::vector<Vertex_handle>::const_iterator it;
PSet.nearest_neighbors(actual,5, std::back_inserter(L));
std::cout << "actual point: " << actual << "\n";
for (it=L.begin();it != L.end(); it++)
std::cout << it->info() << "\n";
return 0;
}
A Vertex_handle is roughly equivalent of a pointer. To access it data member you have to either dereference it or use the -> operator.
If you have a vector of Vertex_handle, then iterator are over Vertex_handle
which means that you have to dereference the iterator to access the Vertex_handle. You should write (*it)->info().
Maybe the confusion came from the fact that the iterators of the triangulation are implicitly convertible to the handle types.
I want to find k nearest neighbors of a series of periodic points using Point_set_2, the following piece of code is the header files and related typedefs, in which I used periodic version of delaunay triangulation:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Periodic_2_Delaunay_triangulation_2.h>
#include <CGAL/Periodic_2_triangulation_traits_2.h>
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
#include <CGAL/Point_set_2.h>
#include <vector>
//******************************************************************
using namespace std;
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Periodic_2_triangulation_traits_2<K> Gt;
typedef CGAL::Triangulation_vertex_base_with_info_2<unsigned, Gt> Vb;
typedef CGAL::Periodic_2_triangulation_face_base_2<Gt> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb, Fb> Tds;
typedef CGAL::Periodic_2_Delaunay_triangulation_2<Gt, Tds> Delaunay;
typedef Delaunay::Iso_rectangle Iso_rectangle;
CGAL::Point_set_2<K,Tds> PSet;
typedef CGAL::Point_set_2<K,Tds>::Edge_iterator Edge_iterator;
typedef CGAL::Point_set_2<K,Tds>::Vertex_handle Vertex_handle;
typedef K::Point_2 Point_2;
typedef vector<pair<Point_2,unsigned> > Vector;
and these are from the main part of the program, in which according to the CGAL manual, I used Delaunay& T in the argument of the function nearest neighbor():
Vector points;
for(int iat = 0; iat < N_b; iat++)
{
points.push_back(make_pair(Point_2(r_b[iat][0],r_b[iat][1]),iat));
}
Iso_rectangle domain(0,0,L[0],L[1]);
Delaunay T(points.begin(), points.end(), domain);
PSet.insert(points.begin(),points.end());
vector<Vertex_handle>::const_iterator it;
vector<Vertex_handle> LV;
for(int iat = 0; iat < N_b; iat++)
{
Point_2 focal(r_b[iat][0], r_b[iat][1]);
PSet.nearest_neighbors(T, focal, nei_top+1, back_inserter(LV));
vector<Vertex_handle>::const_iterator it_begin = LV.begin()+1;
vector<Vertex_handle>::const_iterator it_end = LV.end();
for (it = it_begin; it != it_end; it++)
{
int jat = (*it)->info();
array1[iat]+= sin(theta[jat]-theta[iat]);
}
LV.clear();
}
points.clear();
but it gets a bunch of errors including this one:
OutputIterator nearest_neighbors(Point p, size_type k, OutputIterator res)
^
/usr/include/CGAL/Point_set_2.h:180:20: note: template argument deduction/substitution failed:
In manual, I see the Dt as an argument, but according to the error, such argument doesn't exists!
I am new to CGAL.
I tried to modify Examples/Arrangement_on_surfaces_2 Bezier_curves.cpp to save arrangement to file as shown below:
//! \file examples/Arrangement_on_surface_2/Bezier_curves.cpp
// Constructing an arrangement of Bezier curves.
#include <fstream>
#include <CGAL/basic.h>
#ifndef CGAL_USE_CORE
#include <iostream>
int main ()
{
std::cout << "Sorry, this example needs CORE ..." << std::endl;
return 0;
}
#else
#include <CGAL/Cartesian.h>
#include <CGAL/CORE_algebraic_number_traits.h>
#include <CGAL/Arr_Bezier_curve_traits_2.h>
#include <CGAL/Arrangement_2.h>
#include <CGAL/IO/Arr_iostream.h>
#include "arr_inexact_construction_segments.h"
#include "arr_print.h"
typedef CGAL::CORE_algebraic_number_traits Nt_traits;
typedef Nt_traits::Rational NT;
typedef Nt_traits::Rational Rational;
typedef Nt_traits::Algebraic Algebraic;
typedef CGAL::Cartesian<Rational> Rat_kernel;
typedef CGAL::Cartesian<Algebraic> Alg_kernel;
typedef Rat_kernel::Point_2 Rat_point_2;
typedef CGAL::Arr_Bezier_curve_traits_2<Rat_kernel, Alg_kernel, Nt_traits>
Traits_2;
typedef Traits_2::Curve_2 Bezier_curve_2;
typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
//typedef CGAL::Arrangement_2<Traits_2> Arrangement;
int main (int argc, char *argv[])
{
// Get the name of the input file from the command line, or use the default
// Bezier.dat file if no command-line parameters are given.
const char *filename = (argc > 1) ? argv[1] : "Bezier.dat";
const char *outfilename = (argc > 1) ? argv[1] : "BezierOut.dat";
// Open the input file.
std::ifstream in_file (filename);
if (! in_file.is_open()) {
std::cerr << "Failed to open " << filename << std::endl;
return 1;
}
// Read the curves from the input file.
unsigned int n_curves;
std::list<Bezier_curve_2> curves;
Bezier_curve_2 B;
unsigned int k;
in_file >> n_curves;
for (k = 0; k < n_curves; k++) {
// Read the current curve (specified by its control points).
in_file >> B;
curves.push_back (B);
std::cout << "B = {" << B << "}" << std::endl;
}
in_file.close();
// Construct the arrangement.
Arrangement_2 arr;
insert (arr, curves.begin(), curves.end());
// Print the arrangement size.
std::ofstream out_file;
out_file.open(outfilename);
out_file << "The arrangement size:" << std::endl
<< " V = " << arr.number_of_vertices()
<< ", E = " << arr.number_of_edges()
<< ", F = " << arr.number_of_faces() << std::endl;
out_file << arr;
out_file.close();
return 0;
}
#endif
If I comment out the line out_file << arr; it works fine. Otherwise it generates a C2678 error in read_x_monotone_curve in Arr_text_formtter.h
I am using Visual Studio 15 x86.
Thank you for any help.
I solve this by modifying the print_arrangement(arr) routine in arr_print.h to save_arrangement(arr) with a std::ofstream in place of std::cout.
It appears that the << operator does not work.
If someone else has a better solution I am open to it.
Points of intersections in an arrangement of Bezier curves cannot be represented in an exact manner. Therefore, such an arrangement cannot be saved using the default export (<<) operator and the standard format.
The easiest solution is to store the curves, but this means that the arrangement must be recomputed each time the curves are read. Perhaps other solution could be devised, but they are not implemented.