-
Notifications
You must be signed in to change notification settings - Fork 30
/
SimpleTorusParametrization.h
102 lines (96 loc) · 3.79 KB
/
SimpleTorusParametrization.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#ifndef SIMPLETORUSPARAMETRIZATION_HEADER
#define SIMPLETORUSPARAMETRIZATION_HEADER
#include "Torus.h"
#include "basic.h"
#include <GfxTL/VectorXD.h>
#include <GfxTL/HyperplaneCoordinateSystem.h>
#include <GfxTL/MathHelper.h>
#include <GfxTL/AABox.h>
#include <utility>
#include <MiscLib/Vector.h>
#include <iostream>
class SimpleTorusParametrization
{
public:
SimpleTorusParametrization(const Torus &torus);
void Shape(const Torus &torus);
const Torus &Shape() const { return *m_torus; }
inline void Parameters(const Vec3f &p,
std::pair< float, float > *param) const;
inline bool InSpace(float u, float v, Vec3f *p) const;
inline bool InSpace(float u, float v, Vec3f *p, Vec3f *n) const;
void WrapBitmap(const GfxTL::AABox< GfxTL::Vector2Df > &bbox,
float epsilon, bool *uwrap, bool *vwrap) const;
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 {}
static size_t SerializedSize();
void Serialize(std::ostream *o, bool binary) const;
void Deserialize(std::istream *i, bool binary);
private:
const Torus *m_torus;
GfxTL::HyperplaneCoordinateSystem< float, 3 > m_hcs;
};
void SimpleTorusParametrization::Parameters(const Vec3f &p,
std::pair< float, float > *param) const
{
Vec3f s = p - m_torus->Center();
float planex = s.dot(m_hcs[0].Data());
float planey = s.dot(m_hcs[1].Data());
param->first = std::atan2(planey, planex); // major angle
float minory = s.dot(m_torus->AxisDirection());
float minorx = std::sqrt(planex * planex + planey * planey) - m_torus->MajorRadius();
param->second = std::atan2(minory, minorx); // minor angle
if(m_torus->IsAppleShaped())
{
if(abs(param->second) > m_torus->AppleCutOffAngle())
param->second = GfxTL::Math< float >::Sign(param->second)
* m_torus->AppleCutOffAngle();
}
if(m_torus->MajorRadius() < m_torus->MinorRadius() * 2)
param->first *= m_torus->MajorRadius() + m_torus->MinorRadius();
else
param->first *= m_torus->MajorRadius();
param->second *= m_torus->MinorRadius();
}
bool SimpleTorusParametrization::InSpace(float u, float v, Vec3f *p) const
{
float vangle = v / m_torus->MinorRadius();
float minorx = std::cos(vangle);
float minory = std::sin(vangle);
minorx = m_torus->MinorRadius() * minorx + m_torus->MajorRadius();
minory *= m_torus->MinorRadius();
Vec3f pp = minorx * Vec3f(m_hcs[0].Data()) + minory * m_torus->AxisDirection();
GfxTL::Quaternion< float > q;
float majorRadius = (m_torus->MajorRadius() < m_torus->MinorRadius() * 2)?
m_torus->MajorRadius() + m_torus->MinorRadius() : m_torus->MajorRadius();
float uangle = u / majorRadius;
q.RotationRad(uangle, m_torus->AxisDirection()[0], m_torus->AxisDirection()[1],
m_torus->AxisDirection()[2]);
q.Rotate(pp, p);
*p += m_torus->Center();
return true;
}
bool SimpleTorusParametrization::InSpace(float u, float v, Vec3f *p,
Vec3f *n) const
{
float vangle = v / m_torus->MinorRadius();
float minorx = std::cos(vangle);
float minory = std::sin(vangle);
Vec3f nn = minorx * Vec3f(m_hcs[0].Data()) + minory * m_torus->AxisDirection();
minorx = m_torus->MinorRadius() * minorx + m_torus->MajorRadius();
minory *= m_torus->MinorRadius();
Vec3f pp = minorx * Vec3f(m_hcs[0].Data()) + minory * m_torus->AxisDirection();
GfxTL::Quaternion< float > q;
float majorRadius = (m_torus->MajorRadius() < m_torus->MinorRadius() * 2)?
m_torus->MajorRadius() + m_torus->MinorRadius() : m_torus->MajorRadius();
float uangle = u / majorRadius;
q.RotationRad(uangle, m_torus->AxisDirection()[0], m_torus->AxisDirection()[1],
m_torus->AxisDirection()[2]);
q.Rotate(pp, p);
q.Rotate(nn, n);
*p += m_torus->Center();
return true;
}
#endif