Torus.h
Go to the documentation of this file.
1 #ifndef TORUS_HEADER
2 #define TORUS_HEADER
3 #include "basic.h"
4 #include <MiscLib/Vector.h>
5 #include "PointCloud.h"
7 #include <GfxTL/VectorXD.h>
8 #include <GfxTL/MathHelper.h>
9 #include <ostream>
10 #include <istream>
11 #include <stdio.h>
12 #include <MiscLib/NoShrinkVector.h>
13 
14 #ifndef DLL_LINKAGE
15 #define DLL_LINKAGE
16 #endif
17 
19 {
20 public:
21  enum { RequiredSamples = 4 };
22  bool Init(const MiscLib::Vector< Vec3f >& samples);
23  bool InitAverage(const MiscLib::Vector< Vec3f >& samples);
24  bool Init(bool binary, std::istream* i);
25  void Init(FILE* i);
26  void Init(float* array);
27  inline float Distance(const Vec3f& p) const;
28  inline void Normal(const Vec3f& p, Vec3f* n) const;
29  inline float DistanceAndNormal(const Vec3f& p, Vec3f* n) const;
30  inline float SignedDistance(const Vec3f& p) const;
31  inline float SignedDistanceAndNormal(const Vec3f& p, Vec3f* n) const;
32  inline void Project(const Vec3f& p, Vec3f* pp) const;
33  void Transform(float scale, const Vec3f& translate);
34  const Vec3f& Center() const
35  {
36  return m_center;
37  }
38  const Vec3f& AxisDirection() const
39  {
40  return m_normal;
41  }
42  const float MinorRadius() const
43  {
44  return m_rminor;
45  }
46  const float MajorRadius() const
47  {
48  return m_rmajor;
49  }
50  bool LeastSquaresFit(const PointCloud& pc,
53  bool Fit(const PointCloud& pc,
56  {
57  return LeastSquaresFit(pc, begin, end);
58  }
59  bool IsAppleShaped() const
60  {
61  return m_appleShaped;
62  }
63  float AppleCutOffAngle() const
64  {
65  return m_cutOffAngle;
66  }
67  void Serialize(bool binary, std::ostream* o) const;
68  static size_t SerializedSize();
69  void Serialize(FILE* o) const;
70  void Serialize(float* array) const;
71  static size_t SerializedFloatSize();
72 
73 private:
74  void ComputeAppleParams();
75 
76 private:
77  Vec3f m_normal;
78  Vec3f m_center;
79  float m_rminor;
80  float m_rmajor;
81  bool m_appleShaped; // an apple shaped torus has rminor > rmajor
82  float m_cutOffAngle; // for an apple shaped torus
83  // the minor circle is cut off
84  float m_appleHeight; // height of the "apple" point
85 };
86 
87 float Torus::Distance(const Vec3f& p) const
88 {
89  Vec3f s = p - m_center;
90  float spin1 = m_normal.dot(s);
91  float spin0 = (s - spin1 * m_normal).length();
92  spin0 -= m_rmajor;
93  if (!m_appleShaped)
94  {
95  return abs(std::sqrt(spin0 * spin0 + spin1 * spin1) - m_rminor);
96  }
97  // apple shaped torus distance
98  float minorAngle = std::atan2(spin1, spin0); // minor angle
99  if (abs(minorAngle) < m_cutOffAngle)
100  {
101  return abs(std::sqrt(spin0 * spin0 + spin1 * spin1) - m_rminor);
102  }
103  spin0 += 2 * m_rmajor - m_rminor;
104  if (minorAngle < 0)
105  {
106  spin1 += m_appleHeight;
107  }
108  else
109  {
110  spin1 -= m_appleHeight;
111  }
112  return std::sqrt(spin0 * spin0 + spin1 * spin1);
113 }
114 
115 void Torus::Normal(const Vec3f& p, Vec3f* n) const
116 {
117  Vec3f s = p - m_center, tmp;
118  float spin1 = m_normal.dot(s);
119  float spin0 = (s - (tmp = spin1 * m_normal)).length();
120  spin0 -= m_rmajor;
121  if (m_appleShaped)
122  {
123  float minorAngle = std::atan2(spin1, spin0); // minor angle
124  if (abs(minorAngle) > m_cutOffAngle)
125  {
126  *n = m_normal;
127  if (minorAngle < 0)
128  {
129  *n *= -1;
130  }
131  return;
132  }
133  }
134  Vec3f pln = s.cross(m_normal);
135  Vec3f plx = m_normal.cross(pln);
136  plx.normalize();
137  *n = spin0 * plx + tmp;
138  *n /= std::sqrt(spin0 * spin0 + spin1 * spin1);
139 }
140 
141 float Torus::DistanceAndNormal(const Vec3f& p, Vec3f* n) const
142 {
143  Vec3f s = p - m_center, tmp;
144  float spin1 = m_normal.dot(s);
145  float spin0 = (s - (tmp = spin1 * m_normal)).length();
146  spin0 -= m_rmajor;
147  if (m_appleShaped)
148  {
149  float minorAngle = std::atan2(spin1, spin0); // minor angle
150  if (abs(minorAngle) > m_cutOffAngle)
151  {
152  *n = m_normal;
153  if (minorAngle < 0)
154  {
155  *n *= -1;
156  }
157  spin0 += 2 * m_rmajor - m_rminor;
158  if (minorAngle < 0)
159  {
160  spin1 += m_appleHeight;
161  }
162  else
163  {
164  spin1 -= m_appleHeight;
165  }
166  return std::sqrt(spin0 * spin0 + spin1 * spin1);
167  }
168  }
169  Vec3f pln = s.cross(m_normal);
170  Vec3f plx = m_normal.cross(pln);
171  plx.normalize();
172  *n = spin0 * plx + tmp;
173  float d = std::sqrt(spin0 * spin0 + spin1 * spin1);
174  *n /= d;
175  return abs(d - m_rminor);
176 }
177 
178 float Torus::SignedDistance(const Vec3f& p) const
179 {
180  Vec3f s = p - m_center;
181  float spin1 = m_normal.dot(s);
182  float spin0 = (s - spin1 * m_normal).length();
183  spin0 -= m_rmajor;
184  if (!m_appleShaped)
185  {
186  return std::sqrt(spin0 * spin0 + spin1 * spin1) - m_rminor;
187  }
188  // apple shaped torus distance
189  float minorAngle = std::atan2(spin1, spin0); // minor angle
190  if (abs(minorAngle) < m_cutOffAngle)
191  {
192  return std::sqrt(spin0 * spin0 + spin1 * spin1) - m_rminor;
193  }
194  spin0 += 2 * m_rmajor - m_rminor;
195  if (minorAngle < 0)
196  {
197  spin1 += m_appleHeight;
198  }
199  else
200  {
201  spin1 -= m_appleHeight;
202  }
203  return -std::sqrt(spin0 * spin0 + spin1 * spin1);
204 }
205 
206 float Torus::SignedDistanceAndNormal(const Vec3f& p, Vec3f* n) const
207 {
208  Vec3f s = p - m_center, tmp;
209  float spin1 = m_normal.dot(s);
210  float spin0 = (s - (tmp = spin1 * m_normal)).length();
211  spin0 -= m_rmajor;
212  if (m_appleShaped)
213  {
214  float minorAngle = std::atan2(spin1, spin0); // minor angle
215  if (abs(minorAngle) > m_cutOffAngle)
216  {
217  *n = m_normal;
218  if (minorAngle < 0)
219  {
220  *n *= -1;
221  }
222  spin0 += 2 * m_rmajor - m_rminor;
223  if (minorAngle < 0)
224  {
225  spin1 += m_appleHeight;
226  }
227  else
228  {
229  spin1 -= m_appleHeight;
230  }
231  return -std::sqrt(spin0 * spin0 + spin1 * spin1);
232  }
233  }
234  Vec3f pln = s.cross(m_normal);
235  Vec3f plx = m_normal.cross(pln);
236  plx.normalize();
237  *n = spin0 * plx + tmp;
238  float d = std::sqrt(spin0 * spin0 + spin1 * spin1);
239  *n /= d;
240  return d - m_rminor;
241 }
242 
243 void Torus::Project(const Vec3f& p, Vec3f* pp) const
244 {
245  Vec3f s = p - m_center, tmp;
246  float spin1 = m_normal.dot(s);
247  float spin0 = (s - (tmp = spin1 * m_normal)).length();
248  spin0 -= m_rmajor;
249  if (m_appleShaped)
250  {
251  float minorAngle = std::atan2(spin1, spin0); // minor angle
252  if (abs(minorAngle) > m_cutOffAngle)
253  {
254  *pp = m_center + GfxTL::Math< float >::Sign(minorAngle) * m_normal;
255  return;
256  }
257  }
258  Vec3f pln = s.cross(m_normal);
259  Vec3f plx = m_normal.cross(pln);
260  plx.normalize();
261  float d = std::sqrt(spin0 * spin0 + spin1 * spin1);
262  *pp = m_center + (m_rminor / d) * (spin0 * plx + tmp)
263  + m_rmajor * plx;
264 }
265 
266 #endif
Torus::IsAppleShaped
bool IsAppleShaped() const
Definition: Torus.h:59
GfxTL::sqrt
VectorXD< D, T > sqrt(const VectorXD< D, T > &a)
Definition: VectorXD.h:662
Vector.h
Vec3f::normalize
float normalize()
Definition: basic.h:125
Torus::MinorRadius
const float MinorRadius() const
Definition: Torus.h:42
Vec3f
Definition: basic.h:16
Vec3f::cross
Vec3f cross(const Vec3f &v) const
Definition: basic.h:107
Torus::SignedDistance
float SignedDistance(const Vec3f &p) const
Definition: Torus.h:178
Torus
Definition: Torus.h:18
MiscLib::Vector
Definition: Vector.h:19
VectorXD.h
Torus::Normal
void Normal(const Vec3f &p, Vec3f *n) const
Definition: Torus.h:115
Torus::Distance
float Distance(const Vec3f &p) const
Definition: Torus.h:87
GfxTL::Math::Sign
static ScalarT Sign(ScalarT s)
Definition: MathHelper.h:23
Torus::AxisDirection
const Vec3f & AxisDirection() const
Definition: Torus.h:38
NoShrinkVector.h
armarx::abs
std::vector< T > abs(const std::vector< T > &v)
Definition: VectorHelpers.h:253
Torus::DistanceAndNormal
float DistanceAndNormal(const Vec3f &p, Vec3f *n) const
Definition: Torus.h:141
Torus::SignedDistanceAndNormal
float SignedDistanceAndNormal(const Vec3f &p, Vec3f *n) const
Definition: Torus.h:206
HyperplaneCoordinateSystem.h
PointCloud
Definition: PointCloud.h:69
Torus::Project
void Project(const Vec3f &p, Vec3f *pp) const
Definition: Torus.h:243
Vec3f::dot
float dot(const Vec3f &v) const
Definition: basic.h:92
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:53
PointCloud.h
DLL_LINKAGE
#define DLL_LINKAGE
Definition: basic.h:11
Torus::MajorRadius
const float MajorRadius() const
Definition: Torus.h:46
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:34
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:63