Torus.h
Go to the documentation of this file.
1 #ifndef TORUS_HEADER
2 #define TORUS_HEADER
3 #include <stdio.h>
4 
5 #include <istream>
6 #include <ostream>
7 
8 #include "PointCloud.h"
9 #include "basic.h"
11 #include <GfxTL/MathHelper.h>
12 #include <GfxTL/VectorXD.h>
13 #include <MiscLib/NoShrinkVector.h>
14 #include <MiscLib/Vector.h>
15 
16 #ifndef DLL_LINKAGE
17 #define DLL_LINKAGE
18 #endif
19 
21 {
22 public:
23  enum
24  {
25  RequiredSamples = 4
26  };
27 
28  bool Init(const MiscLib::Vector<Vec3f>& samples);
29  bool InitAverage(const MiscLib::Vector<Vec3f>& samples);
30  bool Init(bool binary, std::istream* i);
31  void Init(FILE* i);
32  void Init(float* array);
33  inline float Distance(const Vec3f& p) const;
34  inline void Normal(const Vec3f& p, Vec3f* n) const;
35  inline float DistanceAndNormal(const Vec3f& p, Vec3f* n) const;
36  inline float SignedDistance(const Vec3f& p) const;
37  inline float SignedDistanceAndNormal(const Vec3f& p, Vec3f* n) const;
38  inline void Project(const Vec3f& p, Vec3f* pp) const;
39  void Transform(float scale, const Vec3f& translate);
40 
41  const Vec3f&
42  Center() const
43  {
44  return m_center;
45  }
46 
47  const Vec3f&
48  AxisDirection() const
49  {
50  return m_normal;
51  }
52 
53  const float
54  MinorRadius() const
55  {
56  return m_rminor;
57  }
58 
59  const float
60  MajorRadius() const
61  {
62  return m_rmajor;
63  }
64 
65  bool LeastSquaresFit(const PointCloud& pc,
68 
69  bool
70  Fit(const PointCloud& pc,
73  {
74  return LeastSquaresFit(pc, begin, end);
75  }
76 
77  bool
78  IsAppleShaped() const
79  {
80  return m_appleShaped;
81  }
82 
83  float
85  {
86  return m_cutOffAngle;
87  }
88 
89  void Serialize(bool binary, std::ostream* o) const;
90  static size_t SerializedSize();
91  void Serialize(FILE* o) const;
92  void Serialize(float* array) const;
93  static size_t SerializedFloatSize();
94 
95 private:
96  void ComputeAppleParams();
97 
98 private:
99  Vec3f m_normal;
100  Vec3f m_center;
101  float m_rminor;
102  float m_rmajor;
103  bool m_appleShaped; // an apple shaped torus has rminor > rmajor
104  float m_cutOffAngle; // for an apple shaped torus
105  // the minor circle is cut off
106  float m_appleHeight; // height of the "apple" point
107 };
108 
109 float
110 Torus::Distance(const Vec3f& p) const
111 {
112  Vec3f s = p - m_center;
113  float spin1 = m_normal.dot(s);
114  float spin0 = (s - spin1 * m_normal).length();
115  spin0 -= m_rmajor;
116  if (!m_appleShaped)
117  {
118  return abs(std::sqrt(spin0 * spin0 + spin1 * spin1) - m_rminor);
119  }
120  // apple shaped torus distance
121  float minorAngle = std::atan2(spin1, spin0); // minor angle
122  if (abs(minorAngle) < m_cutOffAngle)
123  {
124  return abs(std::sqrt(spin0 * spin0 + spin1 * spin1) - m_rminor);
125  }
126  spin0 += 2 * m_rmajor - m_rminor;
127  if (minorAngle < 0)
128  {
129  spin1 += m_appleHeight;
130  }
131  else
132  {
133  spin1 -= m_appleHeight;
134  }
135  return std::sqrt(spin0 * spin0 + spin1 * spin1);
136 }
137 
138 void
139 Torus::Normal(const Vec3f& p, Vec3f* n) const
140 {
141  Vec3f s = p - m_center, tmp;
142  float spin1 = m_normal.dot(s);
143  float spin0 = (s - (tmp = spin1 * m_normal)).length();
144  spin0 -= m_rmajor;
145  if (m_appleShaped)
146  {
147  float minorAngle = std::atan2(spin1, spin0); // minor angle
148  if (abs(minorAngle) > m_cutOffAngle)
149  {
150  *n = m_normal;
151  if (minorAngle < 0)
152  {
153  *n *= -1;
154  }
155  return;
156  }
157  }
158  Vec3f pln = s.cross(m_normal);
159  Vec3f plx = m_normal.cross(pln);
160  plx.normalize();
161  *n = spin0 * plx + tmp;
162  *n /= std::sqrt(spin0 * spin0 + spin1 * spin1);
163 }
164 
165 float
167 {
168  Vec3f s = p - m_center, tmp;
169  float spin1 = m_normal.dot(s);
170  float spin0 = (s - (tmp = spin1 * m_normal)).length();
171  spin0 -= m_rmajor;
172  if (m_appleShaped)
173  {
174  float minorAngle = std::atan2(spin1, spin0); // minor angle
175  if (abs(minorAngle) > m_cutOffAngle)
176  {
177  *n = m_normal;
178  if (minorAngle < 0)
179  {
180  *n *= -1;
181  }
182  spin0 += 2 * m_rmajor - m_rminor;
183  if (minorAngle < 0)
184  {
185  spin1 += m_appleHeight;
186  }
187  else
188  {
189  spin1 -= m_appleHeight;
190  }
191  return std::sqrt(spin0 * spin0 + spin1 * spin1);
192  }
193  }
194  Vec3f pln = s.cross(m_normal);
195  Vec3f plx = m_normal.cross(pln);
196  plx.normalize();
197  *n = spin0 * plx + tmp;
198  float d = std::sqrt(spin0 * spin0 + spin1 * spin1);
199  *n /= d;
200  return abs(d - m_rminor);
201 }
202 
203 float
205 {
206  Vec3f s = p - m_center;
207  float spin1 = m_normal.dot(s);
208  float spin0 = (s - spin1 * m_normal).length();
209  spin0 -= m_rmajor;
210  if (!m_appleShaped)
211  {
212  return std::sqrt(spin0 * spin0 + spin1 * spin1) - m_rminor;
213  }
214  // apple shaped torus distance
215  float minorAngle = std::atan2(spin1, spin0); // minor angle
216  if (abs(minorAngle) < m_cutOffAngle)
217  {
218  return std::sqrt(spin0 * spin0 + spin1 * spin1) - m_rminor;
219  }
220  spin0 += 2 * m_rmajor - m_rminor;
221  if (minorAngle < 0)
222  {
223  spin1 += m_appleHeight;
224  }
225  else
226  {
227  spin1 -= m_appleHeight;
228  }
229  return -std::sqrt(spin0 * spin0 + spin1 * spin1);
230 }
231 
232 float
234 {
235  Vec3f s = p - m_center, tmp;
236  float spin1 = m_normal.dot(s);
237  float spin0 = (s - (tmp = spin1 * m_normal)).length();
238  spin0 -= m_rmajor;
239  if (m_appleShaped)
240  {
241  float minorAngle = std::atan2(spin1, spin0); // minor angle
242  if (abs(minorAngle) > m_cutOffAngle)
243  {
244  *n = m_normal;
245  if (minorAngle < 0)
246  {
247  *n *= -1;
248  }
249  spin0 += 2 * m_rmajor - m_rminor;
250  if (minorAngle < 0)
251  {
252  spin1 += m_appleHeight;
253  }
254  else
255  {
256  spin1 -= m_appleHeight;
257  }
258  return -std::sqrt(spin0 * spin0 + spin1 * spin1);
259  }
260  }
261  Vec3f pln = s.cross(m_normal);
262  Vec3f plx = m_normal.cross(pln);
263  plx.normalize();
264  *n = spin0 * plx + tmp;
265  float d = std::sqrt(spin0 * spin0 + spin1 * spin1);
266  *n /= d;
267  return d - m_rminor;
268 }
269 
270 void
271 Torus::Project(const Vec3f& p, Vec3f* pp) const
272 {
273  Vec3f s = p - m_center, tmp;
274  float spin1 = m_normal.dot(s);
275  float spin0 = (s - (tmp = spin1 * m_normal)).length();
276  spin0 -= m_rmajor;
277  if (m_appleShaped)
278  {
279  float minorAngle = std::atan2(spin1, spin0); // minor angle
280  if (abs(minorAngle) > m_cutOffAngle)
281  {
282  *pp = m_center + GfxTL::Math<float>::Sign(minorAngle) * m_normal;
283  return;
284  }
285  }
286  Vec3f pln = s.cross(m_normal);
287  Vec3f plx = m_normal.cross(pln);
288  plx.normalize();
289  float d = std::sqrt(spin0 * spin0 + spin1 * spin1);
290  *pp = m_center + (m_rminor / d) * (spin0 * plx + tmp) + m_rmajor * plx;
291 }
292 
293 #endif
Torus::IsAppleShaped
bool IsAppleShaped() const
Definition: Torus.h:78
Vector.h
Vec3f::normalize
float normalize()
Definition: basic.h:141
Torus::MinorRadius
const float MinorRadius() const
Definition: Torus.h:54
Vec3f
Definition: basic.h:17
Vec3f::cross
Vec3f cross(const Vec3f &v) const
Definition: basic.h:121
Torus::SignedDistance
float SignedDistance(const Vec3f &p) const
Definition: Torus.h:204
Torus
Definition: Torus.h:20
magic_enum::detail::n
constexpr auto n() noexcept
Definition: magic_enum.hpp:418
MiscLib::Vector
Definition: Vector.h:19
VectorXD.h
Torus::Normal
void Normal(const Vec3f &p, Vec3f *n) const
Definition: Torus.h:139
Torus::Distance
float Distance(const Vec3f &p) const
Definition: Torus.h:110
GfxTL::Math::Sign
static ScalarT Sign(ScalarT s)
Definition: MathHelper.h:25
Torus::AxisDirection
const Vec3f & AxisDirection() const
Definition: Torus.h:48
NoShrinkVector.h
armarx::abs
std::vector< T > abs(const std::vector< T > &v)
Definition: VectorHelpers.h:281
Torus::DistanceAndNormal
float DistanceAndNormal(const Vec3f &p, Vec3f *n) const
Definition: Torus.h:166
Torus::SignedDistanceAndNormal
float SignedDistanceAndNormal(const Vec3f &p, Vec3f *n) const
Definition: Torus.h:233
HyperplaneCoordinateSystem.h
PointCloud
Definition: PointCloud.h:85
GfxTL::sqrt
VectorXD< D, T > sqrt(const VectorXD< D, T > &a)
Definition: VectorXD.h:704
Torus::Project
void Project(const Vec3f &p, Vec3f *pp) const
Definition: Torus.h:271
Vec3f::dot
float dot(const Vec3f &v) const
Definition: basic.h:104
basic.h
Torus::Fit
bool Fit(const PointCloud &pc, MiscLib::Vector< size_t >::const_iterator begin, MiscLib::Vector< size_t >::const_iterator end)
Definition: Torus.h:70
PointCloud.h
DLL_LINKAGE
#define DLL_LINKAGE
Definition: basic.h:12
Torus::MajorRadius
const float MajorRadius() const
Definition: Torus.h:60
pc
Introduction Thank you for taking interest in our work and downloading this software This library implements the algorithm described in the paper R R R Klein Efficient RANSAC for Point Cloud Shape in Computer Graphics Blackwell June If you use this software you should cite the aforementioned paper in any resulting publication Please send comments or bug reports to Ruwen Roland BUT NOT LIMITED THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY OR CONSEQUENTIAL WHETHER IN STRICT OR EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE Example usage This section shows how to use the library to detect the shapes in a point cloud PointCloud pc
Definition: ReadMe.txt:68
MathHelper.h
Torus::Center
const Vec3f & Center() const
Definition: Torus.h:42
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
Torus::AppleCutOffAngle
float AppleCutOffAngle() const
Definition: Torus.h:84