File: discrete_harmonic_coordinates.cpp

package info (click to toggle)
cgal 6.1.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 144,952 kB
  • sloc: cpp: 811,597; ansic: 208,576; sh: 493; python: 411; makefile: 286; javascript: 174
file content (160 lines) | stat: -rw-r--r-- 5,687 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Barycentric_coordinates_2/boundary_coordinates_2.h>
#include <CGAL/Barycentric_coordinates_2/Discrete_harmonic_coordinates_2.h>

// Typedefs.
using Kernel = CGAL::Exact_predicates_exact_constructions_kernel;

using FT      = Kernel::FT;
using Point_2 = Kernel::Point_2;

struct Info {

  Info(const std::string _name) :
  name(_name) { }
  std::string name;
};

using Vertex       = std::pair<Point_2, Info>;
using Point_map    = CGAL::First_of_pair_property_map<Vertex>;
using Vertex_range = std::vector<Vertex>;

using Discrete_harmonic_coordinates_2 =
  CGAL::Barycentric_coordinates::Discrete_harmonic_coordinates_2<Vertex_range, Kernel, Point_map>;
using Policy =
  CGAL::Barycentric_coordinates::Computation_policy_2;

int main() {

  Kernel kernel;
  Point_map point_map;

  // Construct a unit square.
  const std::vector<Vertex> square = {
    std::make_pair(Point_2(0, 0), Info("1")), std::make_pair(Point_2(1, 0), Info("2")),
    std::make_pair(Point_2(1, 1), Info("3")), std::make_pair(Point_2(0, 1), Info("4"))
  };

  // Construct the class with discrete harmonic weights.
  // We do not check for edge cases since we know the exact positions
  // of all our points. We speed up the computation by using the O(n) algorithm.
  const Policy policy = Policy::FAST;
  Discrete_harmonic_coordinates_2 discrete_harmonic_2(square, policy, kernel, point_map);

  // Construct the center point of the unit square.
  const Point_2 center(FT(1) / FT(2), FT(1) / FT(2));

  // Compute discrete harmonic weights for the center point.
  std::list<FT> weights;
  discrete_harmonic_2.weights(center, std::back_inserter(weights));

  std::cout << std::endl << "discrete harmonic weights (center): ";
  for (const FT& weight : weights) {
    std::cout << weight << " ";
  }
  std::cout << std::endl;

  // Compute discrete harmonic coordinates for the center point.
  std::list<FT> coordinates;
  discrete_harmonic_2(center, std::back_inserter(coordinates));

  std::cout << std::endl << "discrete harmonic coordinates (center): ";
  for (const FT& coordinate : coordinates) {
    std::cout << coordinate << " ";
  }
  std::cout << std::endl;

  // Construct several interior points.
  const std::vector<Point_2> interior_points = {
    Point_2(FT(1) / FT(5), FT(1) / FT(5)),
    Point_2(FT(4) / FT(5), FT(1) / FT(5)),
    Point_2(FT(4) / FT(5), FT(4) / FT(5)),
    Point_2(FT(1) / FT(5), FT(4) / FT(5)) };

  // Compute discrete harmonic weights for all interior points.
  std::cout << std::endl << "discrete harmonic weights (interior): " << std::endl << std::endl;

  std::vector<FT> ws;
  for (const auto& query : interior_points) {
    ws.clear();
    discrete_harmonic_2.weights(query, std::back_inserter(ws));
    for (std::size_t i = 0; i < ws.size() - 1; ++i) {
      std::cout << ws[i] << ", ";
    }
    std::cout << ws[ws.size() - 1] << std::endl;
  }

  // Compute discrete harmonic coordinates for all interior point.
  std::cout << std::endl << "discrete harmonic coordinates (interior): " << std::endl << std::endl;

  std::vector<FT> bs;
  for (const auto& query : interior_points) {
    bs.clear();
    discrete_harmonic_2(query, std::back_inserter(bs));
    for (std::size_t i = 0; i < bs.size() - 1; ++i) {
      std::cout << bs[i] << ", ";
    }
    std::cout << bs[bs.size() - 1] << std::endl;
  }

  // Construct 2 boundary points on the second and fourth edges.
  const Point_2 e2(1, FT(4) / FT(5));
  const Point_2 e4(0, FT(4) / FT(5));

  // Compute discrete harmonic coordinates = boundary coordinates
  // for these 2 points one by one.
  coordinates.clear();
  CGAL::Barycentric_coordinates::boundary_coordinates_2(
    square, e2, std::back_inserter(coordinates), kernel, point_map);
  CGAL::Barycentric_coordinates::boundary_coordinates_2(
    square, e4, std::back_inserter(coordinates), kernel, point_map);

  std::cout << std::endl << "boundary coordinates (edge 2 and edge 4): ";
  for (const FT& coordinate : coordinates) {
    std::cout << coordinate << " ";
  }
  std::cout << std::endl;

  // Construct 6 other boundary points: 2 on the first and third edges respectively
  // and 4 at the vertices.
  const std::vector<Point_2> es13 = {
    Point_2(FT(1) / FT(2), 0), // edges
    Point_2(FT(1) / FT(2), 1),

    // vertices
    Point_2(0, 0), Point_2(1, 0),
    Point_2(1, 1), Point_2(0, 1)
  };

  // Compute discrete harmonic coordinates = boundary coordinates for all 6 points.
  std::cout << std::endl << "boundary coordinates (edge 1, edge 3, and vertices): " << std::endl << std::endl;

  for (const auto& query : es13) {
    bs.clear();
    CGAL::Barycentric_coordinates::boundary_coordinates_2(
      square, query, std::back_inserter(bs), point_map); // we can skip kernel here
    for (std::size_t i = 0; i < bs.size() - 1; ++i) {
      std::cout << bs[i] << ", ";
    }
    std::cout << bs[bs.size() - 1] << std::endl;
  }

  // Construct 2 points outside the unit square - one from the left and one from the right.
  // Even if discrete harmonic coordinates may not be valid for some exterior points,
  // we can still do it.
  const Point_2 l(FT(-1) / FT(2), FT(1) / FT(2));
  const Point_2 r(FT(3)  / FT(2), FT(1) / FT(2));

  // Compute discrete harmonic coordinates for all exterior points.
  coordinates.clear();
  discrete_harmonic_2(l, std::back_inserter(coordinates));
  discrete_harmonic_2(r, std::back_inserter(coordinates));

  std::cout << std::endl << "discrete harmonic coordinates (exterior): ";
  for (const FT& coordinate : coordinates) {
    std::cout << coordinate << " ";
  }
  std::cout << std::endl << std::endl;

  return EXIT_SUCCESS;
}