1 #ifndef CYLINDER_HEADER
2 #define CYLINDER_HEADER
24 :
public std::runtime_error
28 enum { RequiredSamples = 2 };
35 bool Init(
const Vec3f& axisDir,
const Vec3f& axisPos,
float radius);
36 bool Init(
const Vec3f& pointA,
const Vec3f& pointB,
38 bool Init(
bool binary, std::istream* i);
40 void Init(
float* array);
41 inline float Distance(
const Vec3f& p)
const;
42 inline void Normal(
const Vec3f& p,
Vec3f* normal)
const;
43 inline float DistanceAndNormal(
const Vec3f& p,
Vec3f* normal)
const;
44 inline float SignedDistance(
const Vec3f& p)
const;
47 void Parameters(
const Vec3f& p,
48 std::pair< float, float >* param)
const;
51 const Vec3f& AxisDirection()
const;
52 Vec3f& AxisDirection();
53 const Vec3f& AxisPosition()
const;
54 Vec3f& AxisPosition();
55 const Vec3f AngularDirection()
const;
56 void RotateAngularDirection(
float radians);
60 template<
class IteratorT >
61 bool LeastSquaresFit(IteratorT begin, IteratorT end);
66 return LeastSquaresFit(
pc, begin, end);
70 void Serialize(
bool binary, std::ostream* o)
const;
71 static size_t SerializedSize();
72 void Serialize(FILE* o)
const;
73 void Serialize(
float* array)
const;
74 static size_t SerializedFloatSize();
76 void Transform(
float scale,
const Vec3f& translate);
79 inline unsigned int Intersect(
const Vec3f& p,
const Vec3f& r,
80 float* first,
float* second)
const;
83 template<
class WeightT >
88 enum { NumParams = 7 };
89 typedef float ScalarType;
91 template<
class IteratorT >
92 ScalarType Chi(
const ScalarType* params, IteratorT begin, IteratorT end,
93 ScalarType*
values, ScalarType* temp)
const
96 int size = end - begin;
97 #pragma omp parallel for schedule(static) reduction(+:chi)
98 for (
int idx = 0; idx < size; ++idx)
101 for (
unsigned int j = 0; j < 3; ++j)
103 s[j] = begin[idx][j] - params[j];
105 ScalarType u = params[5] *
s[1] - params[4] *
s[2];
107 ScalarType
v = params[3] *
s[2] - params[5] *
s[0];
109 v = params[4] *
s[0] - params[3] *
s[1];
112 chi += (
values[idx] = WeightT::Weigh(temp[idx] - params[6]))
118 template<
class IteratorT >
119 void Derivatives(
const ScalarType* params, IteratorT begin, IteratorT end,
120 const ScalarType*
values,
const ScalarType* temp, ScalarType* matrix)
const
122 int size = end - begin;
123 #pragma omp parallel for schedule(static)
124 for (
int idx = 0; idx < size; ++idx)
127 for (
unsigned int j = 0; j < 3; ++j)
129 s[j] = begin[idx][j] - params[j];
131 ScalarType g =
s[0] * begin[idx][0] +
s[1] * begin[idx][1]
132 +
s[2] * begin[idx][2];
133 if (temp[idx] < 1e-6)
135 matrix[idx * NumParams + 0] =
std::sqrt(1 - params[3] * params[3]);
136 matrix[idx * NumParams + 1] =
std::sqrt(1 - params[4] * params[4]);
137 matrix[idx * NumParams + 2] =
std::sqrt(1 - params[5] * params[5]);
141 matrix[idx * NumParams + 0] = (params[3] * g -
s[0]) / temp[idx];
142 matrix[idx * NumParams + 1] = (params[4] * g -
s[1]) / temp[idx];
143 matrix[idx * NumParams + 2] = (params[5] * g -
s[2]) / temp[idx];
145 matrix[idx * NumParams + 3] = g * matrix[idx * NumParams + 0];
146 matrix[idx * NumParams + 4] = g * matrix[idx * NumParams + 1];
147 matrix[idx * NumParams + 5] = g * matrix[idx * NumParams + 2];
148 matrix[idx * NumParams + 6] = -1;
149 WeightT::template DerivWeigh< NumParams >(temp[idx] - params[6],
150 matrix + idx * NumParams);
154 void Normalize(ScalarType* params)
const
156 ScalarType l =
std::sqrt(params[3] * params[3] + params[4] * params[4]
157 + params[5] * params[5]);
158 for (
unsigned int i = 3; i < 6; ++i)
163 float lambda = -(params[0] * params[3] + params[1] * params[4] +
164 params[2] * params[5]);
165 for (
unsigned int i = 0; i < 3; ++i)
167 params[i] = params[i] + lambda * params[i + 3];
177 float m_angularRotatedRadians;
182 Vec3f diff = p - m_axisPos;
183 float lambda = m_axisDir.
dot(diff);
184 float axisDist = (diff - lambda * m_axisDir).length();
185 return abs(axisDist - m_radius);
190 Vec3f diff = p - m_axisPos;
191 float lambda = m_axisDir.
dot(diff);
192 *normal = diff - lambda * m_axisDir;
198 Vec3f diff = p - m_axisPos;
199 float lambda = m_axisDir.
dot(diff);
200 *normal = diff - lambda * m_axisDir;
201 float axisDist = normal->
length();
206 return abs(axisDist - m_radius);
211 Vec3f diff = p - m_axisPos;
212 float lambda = m_axisDir.
dot(diff);
213 float axisDist = (diff - lambda * m_axisDir).length();
214 return axisDist - m_radius;
217 template<
class IteratorT >
221 for (
size_t i = 0; i < 3; ++i)
223 param[i] = m_axisPos[i];
225 for (
size_t i = 0; i < 3; ++i)
227 param[i + 3] = m_axisDir[i];
230 LevMarCylinder< LevMarLSWeight > levMarCylinder;
231 if (!
LevMar(begin, end, levMarCylinder, param))
235 for (
size_t i = 0; i < 3; ++i)
237 m_axisPos[i] = param[i];
239 for (
size_t i = 0; i < 3; ++i)
241 m_axisDir[i] = param[i + 3];
244 m_hcs.FromNormal(m_axisDir);
245 m_angularRotatedRadians = 0;
250 float* first,
float* second)
const
259 float fRSqr = m_radius * m_radius;
262 Vec3f kDiff = p - m_axisPos;
263 Vec3f kP(kDiff.
dot(m_hcs[0]), kDiff.
dot(m_hcs[1]), m_axisDir.dot(kDiff));
267 float fDz = m_axisDir.dot(r);
269 if (
abs(fDz) >= 1.f - 1e-7f)
278 float fA0, fA1, fA2, fDiscr, fRoot, fInv;
285 fA0 = kP[0] * kP[0] + kP[1] * kP[1] - fRSqr;
286 fA1 = kP[0] * kD[0] + kP[1] * kD[1];
287 fA2 = kD[0] * kD[0] + kD[1] * kD[1];
288 fDiscr = fA1 * fA1 - fA0 * fA2;
294 else if (fDiscr > 1e-7f)
297 fRoot =
sqrt(fDiscr);
299 *first = (-fA1 - fRoot) * fInv;
300 *second = (-fA1 + fRoot) * fInv;