libspatialindex API Reference  (git-trunk)
Point.cc
Go to the documentation of this file.
1 /******************************************************************************
2  * Project: libspatialindex - A C++ library for spatial indexing
3  * Author: Marios Hadjieleftheriou, mhadji@gmail.com
4  ******************************************************************************
5  * Copyright (c) 2004, Marios Hadjieleftheriou
6  *
7  * All rights reserved.
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a
10  * copy of this software and associated documentation files (the "Software"),
11  * to deal in the Software without restriction, including without limitation
12  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13  * and/or sell copies of the Software, and to permit persons to whom the
14  * Software is furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be included
17  * in all copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25  * DEALINGS IN THE SOFTWARE.
26 ******************************************************************************/
27 
28 #include <cstring>
29 #include <cmath>
30 #include <limits>
31 
33 
34 using namespace SpatialIndex;
35 
37 = default;
38 
39 Point::Point(const double* pCoords, uint32_t dimension)
40  : m_dimension(dimension)
41 {
42  // no need to initialize m_pCoords to 0 since if a bad_alloc is raised the destructor will not be called.
43  if (m_dimension <= local_dim)
44  m_pCoords = m_local;
45  else
46  m_pCoords = new double[m_dimension];
47  memcpy(m_pCoords, pCoords, m_dimension * sizeof(double));
48 }
49 
51  : m_dimension(p.m_dimension)
52 {
53  // no need to initialize m_pCoords to 0 since if a bad_alloc is raised the destructor will not be called.
54  if (m_dimension <= local_dim)
55  m_pCoords = m_local;
56  else
57  m_pCoords = new double[m_dimension];
58  memcpy(m_pCoords, p.m_pCoords, m_dimension * sizeof(double));
59 }
60 
62 {
63  if (m_dimension > local_dim)
64  delete[] m_pCoords;
65 }
66 
68 {
69  if (this != &p)
70  {
72  memcpy(m_pCoords, p.m_pCoords, m_dimension * sizeof(double));
73  }
74 
75  return *this;
76 }
77 
78 bool Point::operator==(const Point& p) const
79 {
80  if (m_dimension != p.m_dimension)
82  "Point::operator==: Points have different number of dimensions."
83  );
84 
85  for (uint32_t i = 0; i < m_dimension; ++i)
86  {
87  if (
88  m_pCoords[i] < p.m_pCoords[i] - std::numeric_limits<double>::epsilon() ||
89  m_pCoords[i] > p.m_pCoords[i] + std::numeric_limits<double>::epsilon()) return false;
90  }
91 
92  return true;
93 }
94 
95 //
96 // IObject interface
97 //
99 {
100  return new Point(*this);
101 }
102 
103 //
104 // ISerializable interface
105 //
107 {
108  return (sizeof(uint32_t) + m_dimension * sizeof(double));
109 }
110 
111 void Point::loadFromByteArray(const uint8_t* ptr)
112 {
113  uint32_t dimension;
114  memcpy(&dimension, ptr, sizeof(uint32_t));
115  ptr += sizeof(uint32_t);
116 
117  makeDimension(dimension);
118  memcpy(m_pCoords, ptr, m_dimension * sizeof(double));
119  //ptr += m_dimension * sizeof(double);
120 }
121 
122 void Point::storeToByteArray(uint8_t** data, uint32_t& len)
123 {
124  len = getByteArraySize();
125  *data = new uint8_t[len];
126  uint8_t* ptr = *data;
127 
128  memcpy(ptr, &m_dimension, sizeof(uint32_t));
129  ptr += sizeof(uint32_t);
130  memcpy(ptr, m_pCoords, m_dimension * sizeof(double));
131  //ptr += m_dimension * sizeof(double);
132 }
133 
134 //
135 // IShape interface
136 //
137 bool Point::intersectsShape(const IShape& s) const
138 {
139  const Region* pr = dynamic_cast<const Region*>(&s);
140  if (pr != nullptr)
141  {
142  return pr->containsPoint(*this);
143  }
144 
146  "Point::intersectsShape: Not implemented yet!"
147  );
148 }
149 
150 bool Point::containsShape(const IShape&) const
151 {
152  return false;
153 }
154 
155 bool Point::touchesShape(const IShape& s) const
156 {
157  const Point* ppt = dynamic_cast<const Point*>(&s);
158  if (ppt != nullptr)
159  {
160  if (*this == *ppt) return true;
161  return false;
162  }
163 
164  const Region* pr = dynamic_cast<const Region*>(&s);
165  if (pr != nullptr)
166  {
167  return pr->touchesPoint(*this);
168  }
169 
171  "Point::touchesShape: Not implemented yet!"
172  );
173 }
174 
175 void Point::getCenter(Point& out) const
176 {
177  out = *this;
178 }
179 
180 uint32_t Point::getDimension() const
181 {
182  return m_dimension;
183 }
184 
185 void Point::getMBR(Region& out) const
186 {
188 }
189 
190 double Point::getArea() const
191 {
192  return 0.0;
193 }
194 
195 double Point::getMinimumDistance(const IShape& s) const
196 {
197  const Point* ppt = dynamic_cast<const Point*>(&s);
198  if (ppt != nullptr)
199  {
200  return getMinimumDistance(*ppt);
201  }
202 
203  const Region* pr = dynamic_cast<const Region*>(&s);
204  if (pr != nullptr)
205  {
206  return pr->getMinimumDistance(*this);
207  }
208 
210  "Point::getMinimumDistance: Not implemented yet!"
211  );
212 }
213 
214 double Point::getMinimumDistance(const Point& p) const
215 {
216  if (m_dimension != p.m_dimension)
218  "Point::getMinimumDistance: Shapes have different number of dimensions."
219  );
220 
221  double ret = 0.0;
222 
223  for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
224  {
225  ret += std::pow(m_pCoords[cDim] - p.m_pCoords[cDim], 2.0);
226  }
227 
228  return std::sqrt(ret);
229 }
230 
231 double Point::getCoordinate(uint32_t index) const
232 {
233  if (index >= m_dimension)
235 
236  return m_pCoords[index];
237 }
238 
239 void Point::makeInfinite(uint32_t dimension)
240 {
241  makeDimension(dimension);
242  for (uint32_t cIndex = 0; cIndex < m_dimension; ++cIndex)
243  {
244  m_pCoords[cIndex] = std::numeric_limits<double>::max();
245  }
246 }
247 
248 void Point::makeDimension(uint32_t dimension)
249 {
250  if (m_dimension != dimension)
251  {
252  if (m_dimension > local_dim)
253  delete[] m_pCoords;
254 
255  // remember that this is not a constructor. The object will be destructed normally if
256  // something goes wrong (bad_alloc), so we must take care not to leave the object at an intermediate state.
257  m_pCoords = nullptr;
258  m_dimension = dimension;
259 
260  if (m_dimension <= local_dim)
261  m_pCoords = m_local;
262  else
263  m_pCoords = new double[m_dimension];
264  }
265 }
266 
267 std::ostream& SpatialIndex::operator<<(std::ostream& os, const Point& pt)
268 {
269  for (uint32_t cDim = 0; cDim < pt.m_dimension; ++cDim)
270  {
271  os << pt.m_pCoords[cDim] << " ";
272  }
273 
274  return os;
275 }
double * m_pCoords
Definition: Point.h:80
uint32_t getByteArraySize() override
Definition: Point.cc:106
virtual void makeInfinite(uint32_t dimension)
Definition: Point.cc:239
bool touchesShape(const IShape &in) const override
Definition: Point.cc:155
void storeToByteArray(uint8_t **data, uint32_t &length) override
Definition: Point.cc:122
uint32_t m_dimension
Definition: Point.h:79
static constexpr int local_dim
Definition: Point.h:76
virtual bool operator==(const Point &p) const
Definition: Point.cc:78
virtual Point & operator=(const Point &p)
Definition: Point.cc:67
bool intersectsShape(const IShape &in) const override
Definition: Point.cc:137
void loadFromByteArray(const uint8_t *data) override
Definition: Point.cc:111
virtual double getCoordinate(uint32_t index) const
Definition: Point.cc:231
virtual void makeDimension(uint32_t dimension)
Definition: Point.cc:248
uint32_t getDimension() const override
Definition: Point.cc:180
~Point() override
Definition: Point.cc:61
void getCenter(Point &out) const override
Definition: Point.cc:175
bool containsShape(const IShape &in) const override
Definition: Point.cc:150
Point * clone() override
Definition: Point.cc:98
friend class Region
Definition: Point.h:82
double getArea() const override
Definition: Point.cc:190
double getMinimumDistance(const IShape &in) const override
Definition: Point.cc:195
void getMBR(Region &out) const override
Definition: Point.cc:185
double getMinimumDistance(const IShape &in) const override
Definition: Region.cc:230
virtual bool containsPoint(const Point &in) const
Definition: Region.cc:353
virtual bool touchesPoint(const Point &in) const
Definition: Region.cc:367
SIDX_DLL std::ostream & operator<<(std::ostream &os, const Ball &ball)
Definition: Ball.cc:215