225 lines
6.6 KiB
C
225 lines
6.6 KiB
C
|
// 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/v5.1/Stream_lines_2/include/CGAL/Triangular_field_2.h $
|
||
|
// $Id: Triangular_field_2.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
|
||
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||
|
//
|
||
|
//
|
||
|
// Author(s) : Abdelkrim Mebarki <Abdelkrim.Mebarki@sophia.inria.fr>
|
||
|
|
||
|
#ifndef CGAL_TRIANGULAR_FIELD_2_H_
|
||
|
#define CGAL_TRIANGULAR_FIELD_2_H_
|
||
|
|
||
|
#include <CGAL/license/Stream_lines_2.h>
|
||
|
|
||
|
|
||
|
#include <CGAL/Delaunay_triangulation_2.h>
|
||
|
#include <CGAL/Polygon_2_algorithms.h>
|
||
|
#include <CGAL/squared_distance_2.h>
|
||
|
|
||
|
#include <cfloat>
|
||
|
#include <cstdlib>
|
||
|
|
||
|
#include <iostream>
|
||
|
#include <fstream>
|
||
|
#include <list>
|
||
|
#include <cmath>
|
||
|
#include <string>
|
||
|
|
||
|
#include <CGAL/Triangulation_face_base_with_info_2.h>
|
||
|
|
||
|
namespace CGAL {
|
||
|
|
||
|
template <class StreamLinesTraits_2>
|
||
|
class Triangular_field_2
|
||
|
{
|
||
|
public:
|
||
|
typedef Triangular_field_2<StreamLinesTraits_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<StreamLinesTraits_2> Vb;
|
||
|
typedef CGAL::Triangulation_face_base_with_info_2<Vector_2, StreamLinesTraits_2> Fb;
|
||
|
typedef CGAL::Triangulation_data_structure_2<Vb,Fb> TDS;
|
||
|
typedef CGAL::Delaunay_triangulation_2<StreamLinesTraits_2,TDS> 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 <class PointInputIterator, class VectorInputIterator>
|
||
|
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()<minx)
|
||
|
{
|
||
|
minx = p.x();
|
||
|
}
|
||
|
if(p.y()<miny)
|
||
|
{
|
||
|
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 <class PointInputIterator, class VectorInputIterator>
|
||
|
Triangular_field_2(PointInputIterator pBegin, PointInputIterator
|
||
|
pEnd, VectorInputIterator vBegin)
|
||
|
{
|
||
|
fill(pBegin, pEnd, vBegin);
|
||
|
}
|
||
|
|
||
|
inline typename Geom_traits::Iso_rectangle_2 bbox() const;
|
||
|
|
||
|
std::pair<Vector_2,FT> 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<Point_2, Vector_2> field_map;
|
||
|
|
||
|
FT distance(const Point_2 & p, const Point_2 & q)
|
||
|
{
|
||
|
return sqrt( CGAL::squared_distance(p, q) );
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template <class StreamLinesTraits_2>
|
||
|
inline
|
||
|
typename Triangular_field_2<StreamLinesTraits_2>::Geom_traits::Iso_rectangle_2
|
||
|
Triangular_field_2<StreamLinesTraits_2>::bbox() const
|
||
|
{
|
||
|
return typename Geom_traits::Iso_rectangle_2(minx, miny, maxx,
|
||
|
maxy);
|
||
|
}
|
||
|
|
||
|
template <class StreamLinesTraits_2>
|
||
|
bool
|
||
|
Triangular_field_2<StreamLinesTraits_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 <class StreamLinesTraits_2>
|
||
|
typename Triangular_field_2<StreamLinesTraits_2>::Vector_2
|
||
|
Triangular_field_2<StreamLinesTraits_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<Point_2> 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 <class StreamLinesTraits_2>
|
||
|
typename Triangular_field_2<StreamLinesTraits_2>::FT
|
||
|
Triangular_field_2<StreamLinesTraits_2>::get_density_field(const
|
||
|
Point_2 &
|
||
|
p) const
|
||
|
{
|
||
|
return p.x();
|
||
|
}
|
||
|
|
||
|
template<class StreamLinesTraits_2>
|
||
|
typename Triangular_field_2<StreamLinesTraits_2>::FT
|
||
|
Triangular_field_2<StreamLinesTraits_2>::get_integration_step(const
|
||
|
Point_2
|
||
|
&) const
|
||
|
{
|
||
|
return 1.0;
|
||
|
}
|
||
|
|
||
|
template<class StreamLinesTraits_2>
|
||
|
typename Triangular_field_2<StreamLinesTraits_2>::FT
|
||
|
Triangular_field_2<StreamLinesTraits_2>::get_integration_step() const
|
||
|
{
|
||
|
return 1.0;
|
||
|
}
|
||
|
|
||
|
} //namespace CGAL
|
||
|
|
||
|
#endif
|