Point.h
1/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
2 * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
3 * Author(s): David Salinas
4 *
5 * Copyright (C) 2014 Inria
6 *
7 * Modification(s):
8 * - YYYY/MM Author: Description of the modification
9 */
10
11#ifndef POINT_H_
12#define POINT_H_
13
14#include <cmath>
15#include <vector>
16#include <cassert>
17#include <cstddef>
18#include <initializer_list>
19
20class Point_d {
21 public:
22 Point_d(size_t dim = 3) : coords_(dim, 0) { }
23
24 Point_d(const Point_d& other) : coords_(other.coords_) { }
25
26 Point_d(const std::initializer_list<double>& list) : coords_(list) { }
27
28 template<typename CoordsIt>
29 Point_d(CoordsIt begin, CoordsIt end) : coords_(begin, end) { }
30
31 size_t dimension() const {
32 return coords_.size();
33 }
34
35 double x() const {
36 return coords_[0];
37 }
38
39 double y() const {
40 return coords_[1];
41 }
42
43 double z() const {
44 return coords_[2];
45 }
46
47 double& x() {
48 return coords_[0];
49 }
50
51 double& y() {
52 return coords_[1];
53 }
54
55 double& z() {
56 return coords_[2];
57 }
58
59 std::vector<double>::const_iterator begin() const {
60 return coords_.begin();
61 }
62
63 std::vector<double>::const_iterator end() const {
64 return coords_.end();
65 }
66
67 double& operator[](unsigned i) {
68 return coords_[i];
69 }
70
71 const double& operator[](unsigned i) const {
72 return coords_[i];
73 }
74
75 double squared_norm() const {
76 double res = 0;
77 for (auto x : coords_)
78 res += x * x;
79 return res;
80 }
81
82 friend double squared_dist(const Point_d& p1, const Point_d& p2) {
83 assert(p1.dimension() == p2.dimension());
84 double res = 0;
85 for (unsigned i = 0; i < p1.coords_.size(); ++i)
86 res += (p1[i] - p2[i])*(p1[i] - p2[i]);
87 return res;
88 }
89
93 double operator*(const Point_d& other) const {
94 assert(dimension() == other.dimension());
95 double res = 0;
96 for (unsigned i = 0; i < coords_.size(); ++i)
97 res += coords_[i] * other[i];
98 return res;
99 }
100
104 Point_d cross_product(const Point_d& other) {
105 assert(dimension() == 3 && other.dimension() == 3);
106 Point_d res(3);
107 res[0] = (*this)[1] * other[2] - (*this)[2] * other[1];
108 res[1] = (*this)[2] * other[0] - (*this)[0] * other[2];
109 res[2] = (*this)[0] * other[1] - (*this)[1] * other[0];
110 return res;
111 }
112
113 Point_d operator+(const Point_d& other) const {
114 assert(dimension() == other.dimension());
115 Point_d res(dimension());
116 for (unsigned i = 0; i < coords_.size(); ++i)
117 res[i] = (*this)[i] + other[i];
118 return res;
119 }
120
121 Point_d operator*(double lambda) const {
122 Point_d res(dimension());
123 for (unsigned i = 0; i < coords_.size(); ++i)
124 res[i] = (*this)[i] * lambda;
125 return res;
126 }
127
128 Point_d operator/(double lambda) const {
129 Point_d res(dimension());
130 for (unsigned i = 0; i < coords_.size(); ++i)
131 res[i] = (*this)[i] / lambda;
132 return res;
133 }
134
135 Point_d operator-(const Point_d& other) const {
136 assert(dimension() == other.dimension());
137 Point_d res(dimension());
138 for (unsigned i = 0; i < coords_.size(); ++i)
139 res[i] = (*this)[i] - other[i];
140 return res;
141 }
142
143 friend Point_d unit_normal(const Point_d& p1, const Point_d& p2, const Point_d& p3) {
144 assert(p1.dimension() == 3);
145 assert(p2.dimension() == 3);
146 assert(p3.dimension() == 3);
147 Point_d p1p2 = p2 - p1;
148 Point_d p1p3 = p3 - p1;
149 Point_d res(p1p2.cross_product(p1p3));
150 return res / std::sqrt(res.squared_norm());
151 }
152
153 private:
154 std::vector<double> coords_;
155};
156
157#endif // POINT_H_