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 
44  m_pCoords = new double[m_dimension];
45  memcpy(m_pCoords, pCoords, m_dimension * sizeof(double));
46 }
47 
49  : m_dimension(p.m_dimension)
50 {
51  // no need to initialize m_pCoords to 0 since if a bad_alloc is raised the destructor will not be called.
52 
53  m_pCoords = new double[m_dimension];
54  memcpy(m_pCoords, p.m_pCoords, m_dimension * sizeof(double));
55 }
56 
58 {
59  delete[] m_pCoords;
60 }
61 
63 {
64  if (this != &p)
65  {
67  memcpy(m_pCoords, p.m_pCoords, m_dimension * sizeof(double));
68  }
69 
70  return *this;
71 }
72 
73 bool Point::operator==(const Point& p) const
74 {
75  if (m_dimension != p.m_dimension)
77  "Point::operator==: Points have different number of dimensions."
78  );
79 
80  for (uint32_t i = 0; i < m_dimension; ++i)
81  {
82  if (
83  m_pCoords[i] < p.m_pCoords[i] - std::numeric_limits<double>::epsilon() ||
84  m_pCoords[i] > p.m_pCoords[i] + std::numeric_limits<double>::epsilon()) return false;
85  }
86 
87  return true;
88 }
89 
90 //
91 // IObject interface
92 //
94 {
95  return new Point(*this);
96 }
97 
98 //
99 // ISerializable interface
100 //
102 {
103  return (sizeof(uint32_t) + m_dimension * sizeof(double));
104 }
105 
106 void Point::loadFromByteArray(const uint8_t* ptr)
107 {
108  uint32_t dimension;
109  memcpy(&dimension, ptr, sizeof(uint32_t));
110  ptr += sizeof(uint32_t);
111 
112  makeDimension(dimension);
113  memcpy(m_pCoords, ptr, m_dimension * sizeof(double));
114  //ptr += m_dimension * sizeof(double);
115 }
116 
117 void Point::storeToByteArray(uint8_t** data, uint32_t& len)
118 {
119  len = getByteArraySize();
120  *data = new uint8_t[len];
121  uint8_t* ptr = *data;
122 
123  memcpy(ptr, &m_dimension, sizeof(uint32_t));
124  ptr += sizeof(uint32_t);
125  memcpy(ptr, m_pCoords, m_dimension * sizeof(double));
126  //ptr += m_dimension * sizeof(double);
127 }
128 
129 //
130 // IShape interface
131 //
132 bool Point::intersectsShape(const IShape& s) const
133 {
134  const Region* pr = dynamic_cast<const Region*>(&s);
135  if (pr != nullptr)
136  {
137  return pr->containsPoint(*this);
138  }
139 
141  "Point::intersectsShape: Not implemented yet!"
142  );
143 }
144 
145 bool Point::containsShape(const IShape&) const
146 {
147  return false;
148 }
149 
150 bool Point::touchesShape(const IShape& s) const
151 {
152  const Point* ppt = dynamic_cast<const Point*>(&s);
153  if (ppt != nullptr)
154  {
155  if (*this == *ppt) return true;
156  return false;
157  }
158 
159  const Region* pr = dynamic_cast<const Region*>(&s);
160  if (pr != nullptr)
161  {
162  return pr->touchesPoint(*this);
163  }
164 
166  "Point::touchesShape: Not implemented yet!"
167  );
168 }
169 
170 void Point::getCenter(Point& out) const
171 {
172  out = *this;
173 }
174 
175 uint32_t Point::getDimension() const
176 {
177  return m_dimension;
178 }
179 
180 void Point::getMBR(Region& out) const
181 {
183 }
184 
185 double Point::getArea() const
186 {
187  return 0.0;
188 }
189 
190 double Point::getMinimumDistance(const IShape& s) const
191 {
192  const Point* ppt = dynamic_cast<const Point*>(&s);
193  if (ppt != nullptr)
194  {
195  return getMinimumDistance(*ppt);
196  }
197 
198  const Region* pr = dynamic_cast<const Region*>(&s);
199  if (pr != nullptr)
200  {
201  return pr->getMinimumDistance(*this);
202  }
203 
205  "Point::getMinimumDistance: Not implemented yet!"
206  );
207 }
208 
209 double Point::getMinimumDistance(const Point& p) const
210 {
211  if (m_dimension != p.m_dimension)
213  "Point::getMinimumDistance: Shapes have different number of dimensions."
214  );
215 
216  double ret = 0.0;
217 
218  for (uint32_t cDim = 0; cDim < m_dimension; ++cDim)
219  {
220  ret += std::pow(m_pCoords[cDim] - p.m_pCoords[cDim], 2.0);
221  }
222 
223  return std::sqrt(ret);
224 }
225 
226 double Point::getCoordinate(uint32_t index) const
227 {
228  if (index >= m_dimension)
230 
231  return m_pCoords[index];
232 }
233 
234 void Point::makeInfinite(uint32_t dimension)
235 {
236  makeDimension(dimension);
237  for (uint32_t cIndex = 0; cIndex < m_dimension; ++cIndex)
238  {
239  m_pCoords[cIndex] = std::numeric_limits<double>::max();
240  }
241 }
242 
243 void Point::makeDimension(uint32_t dimension)
244 {
245  if (m_dimension != dimension)
246  {
247  delete[] m_pCoords;
248 
249  // remember that this is not a constructor. The object will be destructed normally if
250  // something goes wrong (bad_alloc), so we must take care not to leave the object at an intermediate state.
251  m_pCoords = nullptr;
252 
253  m_dimension = dimension;
254  m_pCoords = new double[m_dimension];
255  }
256 }
257 
258 std::ostream& SpatialIndex::operator<<(std::ostream& os, const Point& pt)
259 {
260  for (uint32_t cDim = 0; cDim < pt.m_dimension; ++cDim)
261  {
262  os << pt.m_pCoords[cDim] << " ";
263  }
264 
265  return os;
266 }
double * m_pCoords
Definition: Point.h:78
uint32_t getByteArraySize() override
Definition: Point.cc:101
virtual void makeInfinite(uint32_t dimension)
Definition: Point.cc:234
bool touchesShape(const IShape &in) const override
Definition: Point.cc:150
void storeToByteArray(uint8_t **data, uint32_t &length) override
Definition: Point.cc:117
uint32_t m_dimension
Definition: Point.h:77
virtual bool operator==(const Point &p) const
Definition: Point.cc:73
virtual Point & operator=(const Point &p)
Definition: Point.cc:62
bool intersectsShape(const IShape &in) const override
Definition: Point.cc:132
void loadFromByteArray(const uint8_t *data) override
Definition: Point.cc:106
virtual double getCoordinate(uint32_t index) const
Definition: Point.cc:226
virtual void makeDimension(uint32_t dimension)
Definition: Point.cc:243
uint32_t getDimension() const override
Definition: Point.cc:175
~Point() override
Definition: Point.cc:57
void getCenter(Point &out) const override
Definition: Point.cc:170
bool containsShape(const IShape &in) const override
Definition: Point.cc:145
Point * clone() override
Definition: Point.cc:93
friend class Region
Definition: Point.h:80
double getArea() const override
Definition: Point.cc:185
double getMinimumDistance(const IShape &in) const override
Definition: Point.cc:190
void getMBR(Region &out) const override
Definition: Point.cc:180
double getMinimumDistance(const IShape &in) const override
Definition: Region.cc:251
virtual bool containsPoint(const Point &in) const
Definition: Region.cc:374
virtual bool touchesPoint(const Point &in) const
Definition: Region.cc:388
SIDX_DLL std::ostream & operator<<(std::ostream &os, const Ball &ball)
Definition: Ball.cc:215