LowStretchTorusParametrization.h
Go to the documentation of this file.
1#ifndef LOWSTRETCHTORUSPARAMETRIZATION_HEADER
2#define LOWSTRETCHTORUSPARAMETRIZATION_HEADER
3#include <utility>
4
5#include "Torus.h"
6#include "basic.h"
7#include <GfxTL/AABox.h>
8#include <GfxTL/Frame.h>
10#include <GfxTL/MathHelper.h>
11#include <GfxTL/VectorXD.h>
12#include <MiscLib/Vector.h>
13
15{
16public:
18 void Shape(const Torus& torus);
19
20 const Torus&
21 Shape() const
22 {
23 return *m_torus;
24 }
25
26 inline void Parameters(const Vec3f& p, std::pair<float, float>* param) const;
27 inline bool InSpace(float u, float v, Vec3f* p) const;
28 inline bool InSpace(float u, float v, Vec3f* p, Vec3f* n) const;
29
30 void
32 float epsilon,
33 bool* uwrap,
34 bool* vwrap) const
35 {
36 *uwrap = false;
37 *vwrap = false;
38 }
39
41 float epsilon,
42 size_t uextent,
43 size_t vextent,
44 MiscLib::Vector<int>* componentImg,
45 MiscLib::Vector<std::pair<int, size_t>>* labels) const;
46 template <class IteratorT>
47 void Optimize(IteratorT begin, IteratorT end, float epsilon);
48 static size_t SerializedSize();
49 void Serialize(std::ostream* o, bool binary) const;
50 void Deserialize(std::istream* i, bool binary);
51
52private:
53 float MinorFrameRotation() const;
54 float MajorFrameRotation() const;
55
56private:
57 const Torus* m_torus;
59 GfxTL::Frame<2, float> m_minorFrame;
60};
61
62void
63LowStretchTorusParametrization::Parameters(const Vec3f& p, std::pair<float, float>* param) const
64{
65 Vec3f s = p - m_torus->Center();
66 float planex = s.dot(m_hcs[0].Data());
67 float planey = s.dot(m_hcs[1].Data());
68 param->first = std::atan2(planey, planex); // major angle
69 GfxTL::Vector2Df minorVec, minorL;
70 minorVec[1] = s.dot(m_torus->AxisDirection());
71 minorVec[0] = std::sqrt(planex * planex + planey * planey) - m_torus->MajorRadius();
72 float majorRadiusAngle = std::atan2(minorVec[1], minorVec[0]);
73 m_minorFrame.ToLocal(minorVec, &minorL);
74 param->second = std::atan2(minorL[1], minorL[0]); // minor angle
75 if (m_torus->IsAppleShaped())
76 {
77 if (abs(param->second) > m_torus->AppleCutOffAngle())
78 param->second = GfxTL::Math<float>::Sign(param->second) * m_torus->AppleCutOffAngle();
79 }
80 // multiply major angle with radius
81 float majorRadius =
82 m_torus->MajorRadius() + std::cos(majorRadiusAngle) * m_torus->MinorRadius();
83 param->first = param->first * majorRadius;
84 param->second *= m_torus->MinorRadius();
85}
86
87bool
89{
90 float vangle = v / m_torus->MinorRadius();
91 GfxTL::Vector2Df minorVec, minorL;
92 minorL[0] = std::cos(vangle);
93 minorL[1] = std::sin(vangle);
94 m_minorFrame.ToGlobal(minorL, &minorVec);
95 float majorRadiusAngle = std::atan2(minorVec[1], minorVec[0]);
96 minorVec[0] = m_torus->MinorRadius() * minorVec[0] + m_torus->MajorRadius();
97 minorVec[1] *= m_torus->MinorRadius();
98 Vec3f pp = minorVec[0] * Vec3f(m_hcs[0].Data()) + minorVec[1] * m_torus->AxisDirection();
100 float majorRadius =
101 m_torus->MajorRadius() + std::cos(majorRadiusAngle) * m_torus->MinorRadius();
102 float uangle = u / majorRadius;
103 q.RotationRad(uangle,
104 m_torus->AxisDirection()[0],
105 m_torus->AxisDirection()[1],
106 m_torus->AxisDirection()[2]);
107 q.Rotate(pp, p);
108 *p += m_torus->Center();
109 return true;
110}
111
112bool
114{
115 float vangle = v / m_torus->MinorRadius();
116 GfxTL::Vector2Df minorVec, minorL;
117 minorL[0] = std::cos(vangle);
118 minorL[1] = std::sin(vangle);
119 m_minorFrame.ToGlobal(minorL, &minorVec);
120 float majorRadiusAngle = std::atan2(minorVec[1], minorVec[0]);
121 Vec3f nn = minorVec[0] * Vec3f(m_hcs[0].Data()) + minorVec[1] * m_torus->AxisDirection();
122 minorVec[0] = m_torus->MinorRadius() * minorVec[0] + m_torus->MajorRadius();
123 minorVec[1] *= m_torus->MinorRadius();
124 Vec3f pp = minorVec[0] * Vec3f(m_hcs[0].Data()) + minorVec[1] * m_torus->AxisDirection();
126 float majorRadius =
127 m_torus->MajorRadius() + std::cos(majorRadiusAngle) * m_torus->MinorRadius();
128 float uangle = u / majorRadius;
129 q.RotationRad(uangle,
130 m_torus->AxisDirection()[0],
131 m_torus->AxisDirection()[1],
132 m_torus->AxisDirection()[2]);
133 q.Rotate(pp, p);
134 q.Rotate(nn, n);
135 *p += m_torus->Center();
136 return true;
137}
138
139template <class IteratorT>
140void
141LowStretchTorusParametrization::Optimize(IteratorT begin, IteratorT end, float epsilon)
142{
143 // tries to find a rotation of the parametrization that does not cut
144 // the points
145 // find a rotation along the major radius (u-direction) and minor radius (v-direction)
147 nframe.FromNormal(m_torus->AxisDirection());
148 MiscLib::Vector<float> uangles(end - begin), vangles(end - begin);
149 size_t j = 0;
150 for (IteratorT i = begin; i != end; ++i, ++j)
151 {
152 Vec3f s = *i - m_torus->Center();
153 float planex = s.dot(nframe[0].Data());
154 float planey = s.dot(nframe[1].Data());
155 uangles[j] = std::atan2(planey, planex); // major angle
156 GfxTL::Vector2Df minorVec;
157 minorVec[1] = s.dot(m_torus->AxisDirection());
158 minorVec[0] = std::sqrt(planex * planex + planey * planey) - m_torus->MajorRadius();
159 vangles[j] = std::atan2(minorVec[1], minorVec[0]); // minor angle
160 if (m_torus->IsAppleShaped())
161 {
162 if (abs(uangles[j]) > m_torus->AppleCutOffAngle())
163 uangles[j] = GfxTL::Math<float>::Sign(uangles[j]) * m_torus->AppleCutOffAngle();
164 }
165 }
166 std::sort(vangles.begin(), vangles.end());
167 std::sort(uangles.begin(), uangles.end());
168 // try to find a large gap along u direction
169 float maxGap = uangles.front() + 2 * float(M_PI) - uangles.back();
170 float lower = uangles.back(), upper = uangles.front() + 2 * float(M_PI);
171 for (size_t i = 1; i < uangles.size(); ++i)
172 {
173 float gap = uangles[i] - uangles[i - 1];
174 if (gap > maxGap)
175 {
176 maxGap = gap;
177 lower = uangles[i - 1];
178 upper = uangles[i];
179 }
180 }
181 // rotate m_hcs into gap
182 float rotationAngle = (lower + upper) / 2;
183 nframe.RotateOnNormal(rotationAngle + float(M_PI));
184 m_hcs[0] = nframe[0];
185 m_hcs[1] = nframe[1];
186 // try to find a large gap along v direction
187 maxGap = vangles.front() + 2 * float(M_PI) - vangles.back();
188 lower = vangles.back();
189 upper = vangles.front() + 2 * float(M_PI);
190 for (size_t i = 1; i < vangles.size(); ++i)
191 {
192 float gap = vangles[i] - vangles[i - 1];
193 if (gap > maxGap)
194 {
195 maxGap = gap;
196 lower = vangles[i - 1];
197 upper = vangles[i];
198 }
199 }
200 rotationAngle = (lower + upper) / 2;
201 m_minorFrame.Canonical();
202 m_minorFrame.RotateFrame(rotationAngle + float(M_PI));
203}
204
205#endif
#define float
Definition 16_Level.h:22
#define M_PI
Definition MathTools.h:17
static ScalarT Sign(ScalarT s)
Definition MathHelper.h:25
void WrapComponents(const GfxTL::AABox< GfxTL::Vector2Df > &bbox, float epsilon, size_t uextent, size_t vextent, MiscLib::Vector< int > *componentImg, MiscLib::Vector< std::pair< int, size_t > > *labels) const
void Deserialize(std::istream *i, bool binary)
void Serialize(std::ostream *o, bool binary) const
void WrapBitmap(const GfxTL::AABox< GfxTL::Vector2Df > &bbox, float epsilon, bool *uwrap, bool *vwrap) const
void Optimize(IteratorT begin, IteratorT end, float epsilon)
bool InSpace(float u, float v, Vec3f *p) const
void Parameters(const Vec3f &p, std::pair< float, float > *param) const
size_type size() const
Definition Vector.h:215
Definition Torus.h:21
Definition basic.h:18
#define q
VectorXD< 2, float > Vector2Df
Definition VectorXD.h:716