libspatialindex API Reference  (git-trunk)
Ball.cc
Go to the documentation of this file.
1 /******************************************************************************
2  * Project: libspatialindex - A C++ library for spatial indexing
3  * Author: Peter Labadorf - plaba3.1415@gmail.com
4  ******************************************************************************
5  * Copyright (c) 2023, Peter Labadorf
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 <cmath>
29 #include <cstring>
30 #include <limits>
31 
33 
34 using namespace SpatialIndex;
35 
36 Ball::Ball()
37 = default;
38 
39 Ball::Ball(const Ball &b)
40 {
42  m_radius = b.m_radius;
43 }
44 
45 Ball::Ball(double radius, const Point &center)
46 {
47  m_centerPoint = center;
48  m_radius = radius;
49 }
50 
51 Ball::Ball(double radius, const double *pCoords, uint32_t dimension)
52 {
53  m_centerPoint = Point(pCoords, dimension);
54  m_radius = radius;
55 }
56 
58 = default;
59 
61 {
62  if(this != &b)
63  {
64  m_radius = b.m_radius;
66  }
67  return *this;
68 }
69 
70 bool Ball::operator==(const Ball &b) const
71 {
72  return fabs(m_radius - b.m_radius) <= std::numeric_limits<double>::epsilon()
74 }
75 
76 //
77 // IObject interface
78 //
80 {
81  return new Ball(*this);
82 }
83 
84 //
85 // ISerializable interface
86 //
88 {
89  return m_centerPoint.getByteArraySize() + sizeof(double);
90 }
91 
92 void Ball::loadFromByteArray(const uint8_t *data)
93 {
96  memcpy(&m_radius, data, sizeof(double));
97 }
98 
99 void Ball::storeToByteArray(uint8_t **data, uint32_t &length)
100 {
101  uint32_t center_point_size;
102  length = getByteArraySize();
103 
104  *data = new uint8_t[length];
105  uint8_t *ptr = *data;
106 
107  m_centerPoint.storeToByteArray(&ptr, center_point_size);
108 
109  ptr += center_point_size;
110  memcpy(ptr, &m_radius, sizeof(double));
111 }
112 
113 //
114 // IShape interface
115 //
116 bool Ball::intersectsShape(const IShape &in) const
117 {
119 }
120 
121 bool Ball::containsShape(const IShape &in) const
122 {
125  "Ball::containsShape: Shape has the wrong number of dimensions."
126  );
127 
128  const Point *point = dynamic_cast<const Point*>(&in);
129  if (point != nullptr) return containsPoint(point);
130 
131  const LineSegment *line = dynamic_cast<const LineSegment*>(&in);
132  if (line != nullptr) return containsLineSegment(line);
133 
134  const Region *region = dynamic_cast<const Region*>(&in);
135  if (region != nullptr) return containsRegion(region);
136 
137  const Ball *ball = dynamic_cast<const Ball*>(&in);
138  if (ball != nullptr) return containsBall(ball);
139 
141  "Ball::intersectsShape: Not implemented yet!"
142  );
143 }
144 
145 bool Ball::touchesShape(const IShape &in) const
146 {
147  return fabs(in.getMinimumDistance(m_centerPoint) - m_radius) <=
148  std::numeric_limits<double>::epsilon();
149 }
150 
151 void Ball::getCenter(Point &out) const
152 {
153  out = m_centerPoint;
154 }
155 
156 uint32_t Ball::getDimension() const
157 {
158  return m_centerPoint.m_dimension;
159 }
160 
161 void Ball::getMBR(Region &out) const
162 {
164  for (uint16_t i = 0; i < m_centerPoint.m_dimension; i++)
165  {
166  out.m_pLow[i] -= m_radius;
167  out.m_pHigh[i] += m_radius;
168  }
169 }
170 
171 double Ball::getArea() const
172 {
173  return std::pow(m_radius, m_centerPoint.m_dimension) *
174  std::pow(M_PI, m_centerPoint.m_dimension / 2) /
175  std::tgamma(m_centerPoint.m_dimension / 2 + 1);
176 }
177 
178 double Ball::getMinimumDistance(const IShape &in) const
179 {
180  return std::max(in.getMinimumDistance(m_centerPoint) - m_radius, 0.0);
181 }
182 
183 bool Ball::containsRegion(const Region *region) const
184 {
185  double sum = 0;
186  for (uint32_t i = 0; i < m_centerPoint.m_dimension; i++)
187  {
188  double furthest = std::max(std::abs(m_centerPoint.m_pCoords[i] - region->m_pLow[i]),
189  std::abs(region->m_pHigh[i] - m_centerPoint.m_pCoords[i]));
190  sum += furthest * furthest;
191  }
192  return sum <= m_radius * m_radius;
193 }
194 
195 bool Ball::containsLineSegment(const LineSegment *line) const
196 {
197  double sum = 0;
198  for (uint32_t i = 0; i < m_centerPoint.m_dimension; i++)
199  {
200  double d = line->m_pStartPoint[i] - m_centerPoint.m_pCoords[i];
201  sum += d * d;
202  }
203  if (sum > m_radius * m_radius) return false;
204 
205  sum = 0;
206  for (uint32_t i = 0; i < m_centerPoint.m_dimension; i++)
207  {
208  double d = line->m_pEndPoint[i] - m_centerPoint.m_pCoords[i];
209  sum += d * d;
210  }
211 
212  return sum <= m_radius * m_radius;
213 }
214 
215 std::ostream &SpatialIndex::operator<<(std::ostream &os, const Ball &ball)
216 {
217  os << ball.m_centerPoint << " " << ball.m_radius << " ";
218  return os;
219 }
#define M_PI
Definition: Ball.h:31
void getMBR(SpatialIndex::Region &out) const override
Definition: Ball.cc:161
bool touchesShape(const IShape &in) const override
Definition: Ball.cc:145
virtual bool containsLineSegment(const SpatialIndex::LineSegment *line) const
Definition: Ball.cc:195
void loadFromByteArray(const uint8_t *data) override
Definition: Ball.cc:92
bool containsPoint(const Point *point) const
Definition: Ball.h:79
virtual bool operator==(const Ball &b) const
Definition: Ball.cc:70
Point m_centerPoint
Definition: Ball.h:91
void getCenter(SpatialIndex::Point &out) const override
Definition: Ball.cc:151
Ball * clone() override
Definition: Ball.cc:79
bool containsShape(const IShape &in) const override
Definition: Ball.cc:121
void storeToByteArray(uint8_t **data, uint32_t &length) override
Definition: Ball.cc:99
double m_radius
Definition: Ball.h:90
double getArea() const override
Definition: Ball.cc:171
bool intersectsShape(const IShape &in) const override
Definition: Ball.cc:116
bool containsBall(const Ball *ball) const
Definition: Ball.h:84
uint32_t getByteArraySize() override
Definition: Ball.cc:87
uint32_t getDimension() const override
Definition: Ball.cc:156
virtual Ball & operator=(const Ball &b)
Definition: Ball.cc:60
virtual bool containsRegion(const SpatialIndex::Region *region) const
Definition: Ball.cc:183
double getMinimumDistance(const IShape &in) const override
Definition: Ball.cc:178
virtual double getMinimumDistance(const IShape &in) const =0
virtual uint32_t getDimension() const =0
double * m_pCoords
Definition: Point.h:78
uint32_t getByteArraySize() override
Definition: Point.cc:101
void storeToByteArray(uint8_t **data, uint32_t &length) override
Definition: Point.cc:117
uint32_t m_dimension
Definition: Point.h:77
void loadFromByteArray(const uint8_t *data) override
Definition: Point.cc:106
double * m_pHigh
Definition: Region.h:99
double * m_pLow
Definition: Region.h:98
SIDX_DLL std::ostream & operator<<(std::ostream &os, const Ball &ball)
Definition: Ball.cc:215