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>
14#include <MiscLib/Vector.h>
15
16#ifndef DLL_LINKAGE
17#define DLL_LINKAGE
18#endif
19
21{
22public:
23 enum
24 {
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&
49 {
50 return m_normal;
51 }
52
53 const float
55 {
56 return m_rminor;
57 }
58
59 const float
61 {
62 return m_rmajor;
63 }
64
65 bool LeastSquaresFit(const PointCloud& pc,
68
69 bool
76
77 bool
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
95private:
96 void ComputeAppleParams();
97
98private:
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
109float
110Torus::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
138void
139Torus::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
165float
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
203float
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
232float
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
270void
271Torus::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
#define DLL_LINKAGE
Definition basic.h:12
static ScalarT Sign(ScalarT s)
Definition MathHelper.h:25
Definition Torus.h:21
bool IsAppleShaped() const
Definition Torus.h:78
const Vec3f & Center() const
Definition Torus.h:42
float SignedDistance(const Vec3f &p) const
Definition Torus.h:204
bool LeastSquaresFit(const PointCloud &pc, MiscLib::Vector< size_t >::const_iterator begin, MiscLib::Vector< size_t >::const_iterator end)
Definition Torus.cpp:538
void Normal(const Vec3f &p, Vec3f *n) const
Definition Torus.h:139
const float MajorRadius() const
Definition Torus.h:60
void Project(const Vec3f &p, Vec3f *pp) const
Definition Torus.h:271
const Vec3f & AxisDirection() const
Definition Torus.h:48
float DistanceAndNormal(const Vec3f &p, Vec3f *n) const
Definition Torus.h:166
float AppleCutOffAngle() const
Definition Torus.h:84
bool Fit(const PointCloud &pc, MiscLib::Vector< size_t >::const_iterator begin, MiscLib::Vector< size_t >::const_iterator end)
Definition Torus.h:70
float Distance(const Vec3f &p) const
Definition Torus.h:110
@ RequiredSamples
Definition Torus.h:25
const float MinorRadius() const
Definition Torus.h:54
float SignedDistanceAndNormal(const Vec3f &p, Vec3f *n) const
Definition Torus.h:233
Definition basic.h:18
Vec3f cross(const Vec3f &v) const
Definition basic.h:121
float normalize()
Definition basic.h:141
float dot(const Vec3f &v) const
Definition basic.h:104