26 :
public std::runtime_error
29 :
std::runtime_error(
"Parallel planes in cone construction")
32 enum { RequiredSamples = 3 };
42 bool Init(
bool binary, std::istream* i);
44 void Init(
float* array);
45 inline float Distance(
const Vec3f& p)
const;
46 inline void Normal(
const Vec3f& p,
Vec3f* n)
const;
47 inline float DistanceAndNormal(
const Vec3f& p,
Vec3f* n)
const;
48 inline float SignedDistance(
const Vec3f& p)
const;
49 inline float SignedDistanceAndNormal(
const Vec3f& p,
Vec3f* n)
const;
52 void Parameters(
const Vec3f& p,
53 std::pair< float, float >* param)
const;
54 inline float Height(
const Vec3f& p)
const;
55 inline float Angle()
const;
56 inline const Vec3f& Center()
const;
57 inline const Vec3f& AxisDirection()
const;
62 inline const Vec3f AngularDirection()
const;
64 void RotateAngularDirection(
float radians);
65 inline float RadiusAtLength(
float length)
const;
69 template<
class IteratorT >
70 bool LeastSquaresFit(IteratorT begin, IteratorT end);
75 return LeastSquaresFit(
pc, begin, end);
79 void Serialize(
bool binary, std::ostream* o)
const;
80 static size_t SerializedSize();
81 void Serialize(FILE* o)
const;
82 void Serialize(
float* array)
const;
83 static size_t SerializedFloatSize();
84 void Transform(
float scale,
const Vec3f& translate);
87 inline unsigned int Intersect(
const Vec3f& p,
const Vec3f& r,
88 float lambda[2],
Vec3f interPts[2])
const;
91 template<
class WeightT >
96 enum { NumParams = 7 };
97 typedef float ScalarType;
99 template<
class IteratorT >
100 ScalarType Chi(
const ScalarType* params, IteratorT begin, IteratorT end,
101 ScalarType*
values, ScalarType* temp)
const
104 ScalarType cosPhi = std::cos(params[6]);
105 ScalarType sinPhi = std::sin(params[6]);
106 int size = end - begin;
107 #pragma omp parallel for schedule(static) reduction(+:chi)
108 for (
int idx = 0; idx < size; ++idx)
111 for (
unsigned int j = 0; j < 3; ++j)
113 s[j] = begin[idx][j] - params[j];
115 ScalarType g =
abs(
s[0] * params[3] +
s[1] * params[4] +
s[2] * params[5]);
116 ScalarType f =
s.sqrLength() - (g * g);
126 chi += (
values[idx] = WeightT::Weigh(cosPhi * f - sinPhi * g))
132 template<
class IteratorT >
133 void Derivatives(
const ScalarType* params, IteratorT begin, IteratorT end,
134 const ScalarType*
values,
const ScalarType* temp, ScalarType* matrix)
const
136 ScalarType sinPhi = -std::sin(params[6]);
137 ScalarType cosPhi = std::cos(params[6]);
138 int size = end - begin;
139 #pragma omp parallel for schedule(static)
140 for (
int idx = 0; idx < size; ++idx)
143 for (
unsigned int j = 0; j < 3; ++j)
145 s[j] = begin[idx][j] - params[j];
147 ScalarType g =
abs(
s[0] * params[3] +
s[1] * params[4] +
s[2] * params[5]);
148 ScalarType ggradient[6];
149 for (
unsigned int j = 0; j < 3; ++j)
151 ggradient[j] = -params[j + 3];
153 for (
unsigned int j = 0; j < 3; ++j)
155 ggradient[j + 3] =
s[j] - params[j + 3] * g;
157 ScalarType fgradient[6];
158 if (temp[idx] < 1e-6)
160 fgradient[0] =
std::sqrt(1 - params[3] * params[3]);
161 fgradient[1] =
std::sqrt(1 - params[4] * params[4]);
162 fgradient[2] =
std::sqrt(1 - params[5] * params[5]);
166 fgradient[0] = (params[3] * g -
s[0]) / temp[idx];
167 fgradient[1] = (params[4] * g -
s[1]) / temp[idx];
168 fgradient[2] = (params[5] * g -
s[2]) / temp[idx];
170 fgradient[3] = g * fgradient[0];
171 fgradient[4] = g * fgradient[1];
172 fgradient[5] = g * fgradient[2];
173 for (
unsigned int j = 0; j < 6; ++j)
174 matrix[idx * NumParams + j] =
175 cosPhi * fgradient[j] + sinPhi * ggradient[j];
176 matrix[idx * NumParams + 6] = temp[idx] * sinPhi - g * cosPhi;
177 WeightT::template DerivWeigh< NumParams >(cosPhi * temp[idx] + sinPhi * g,
178 matrix + idx * NumParams);
182 void Normalize(
float* params)
const
185 ScalarType l =
std::sqrt(params[3] * params[3] + params[4] * params[4] +
186 params[5] * params[5]);
187 for (
unsigned int i = 3; i < 6; ++i)
192 params[6] -= std::floor(params[6] / (2 * ScalarType(
M_PI))) * (2 * ScalarType(
M_PI));
193 if (params[6] >
M_PI)
195 params[6] -= std::floor(params[6] / ScalarType(
M_PI)) * ScalarType(
M_PI);
196 for (
unsigned int i = 3; i < 6; ++i)
201 if (params[6] > ScalarType(
M_PI) / 2)
203 params[6] = ScalarType(
M_PI) - params[6];
216 float m_angularRotatedRadians;
223 float g =
s.dot(m_axisDir);
226 float sqrS =
s.sqrLength();
227 float f = sqrS - (g * g);
236 float da = m_n2d[0] * f;
237 float db = m_n2d[1] * g;
238 if (g < 0 && da - db < 0)
248 Vec3f pln =
s.cross(m_axisDir);
252 *n = m_normal[0] * plx + m_normalY;
259 float g =
s.dot(m_axisDir);
262 float sqrS =
s.sqrLength();
263 float f = sqrS - (g * g);
272 float da = m_n2d[0] * f;
273 float db = m_n2d[1] * g;
275 if (g < 0 && da - db < 0)
284 Vec3f plx =
s - g * m_axisDir;
286 *n = m_normal[0] * plx + m_normalY;
294 float g =
s.dot(m_axisDir);
297 float sqrS =
s.sqrLength();
298 float f = sqrS - (g * g);
307 float da = m_n2d[0] * f;
308 float db = m_n2d[1] * g;
309 if (g < 0 && da - db < 0)
320 float g =
s.dot(m_axisDir);
323 float sqrS =
s.sqrLength();
324 float f = sqrS - (g * g);
333 float da = m_n2d[0] * f;
334 float db = m_n2d[1] * g;
336 if (g < 0 && da - db < 0)
345 Vec3f plx =
s - g * m_axisDir;
347 *n = m_normal[0] * plx + m_normalY;
368 return Vec3f(m_hcs[0].Data());
373 return std::sin(m_angle) *
abs(length);
379 return m_axisDir.
dot(
s);
382 template<
class IteratorT >
386 for (
unsigned int i = 0; i < 3; ++i)
388 param[i] = m_center[i];
390 for (
unsigned int i = 0; i < 3; ++i)
392 param[i + 3] = m_axisDir[i];
395 LevMarCone< LevMarLSWeight > levMarCone;
396 if (!
LevMar(begin, end, levMarCone, param))
400 if (param[6] < 1e-6 || param[6] >
float(
M_PI) / 2 - 1e-6)
404 for (
unsigned int i = 0; i < 3; ++i)
406 m_center[i] = param[i];
408 for (
unsigned int i = 0; i < 3; ++i)
410 m_axisDir[i] = param[i + 3];
413 m_normal =
Vec3f(std::cos(-m_angle), std::sin(-m_angle), 0);
414 m_normalY = m_normal[1] * m_axisDir;
415 m_n2d[0] = std::cos(m_angle);
416 m_n2d[1] = -std::sin(m_angle);
417 m_hcs.FromNormal(m_axisDir);
418 m_angularRotatedRadians = 0;
425 intptr_t size = end - begin;
426 #ifndef _WIN64 // for some reason the Microsoft x64 compiler crashes at the next line
427 #pragma omp parallel for schedule(static) reduction(+:heightSum)
429 for (intptr_t i = 0; i < size; ++i)
431 heightSum +=
Height(begin[i]);
436 m_hcs.FromNormal(m_axisDir);
442 float lambda[2],
Vec3f interPts[2])
const
458 float fAdD = m_axisDir.dot(r);
459 float tmp, fCosSqr = (tmp = cos(m_angle)) * tmp;
460 Vec3f kE = p - m_center;
461 float fAdE = m_axisDir.
dot(kE);
462 float fDdE = r.
dot(kE);
463 float fEdE = kE.
dot(kE);
464 float fC2 = fAdD * fAdD - fCosSqr;
465 float fC1 = fAdD * fAdE - fCosSqr * fDdE;
466 float fC0 = fAdE * fAdE - fCosSqr * fEdE;
470 unsigned int interCount = 0;
471 if (
abs(fC2) >= 1e-7)
474 float fDiscr = fC1 * fC1 - fC0 * fC2;
475 if (fDiscr < (
float)0.0)
481 else if (fDiscr > 1e-7)
487 float fRoot =
sqrt(fDiscr);
488 float fInvC2 = ((
float)1.0) / fC2;
491 float fT = (-fC1 - fRoot) * fInvC2;
494 interPts[interCount] = p + fT * r;
495 kE = interPts[interCount] - m_center;
496 fdot = kE.
dot(m_axisDir);
497 if (fdot > (
float)0.0)
499 lambda[interCount] = fT;
504 fT = (-fC1 + fRoot) * fInvC2;
507 interPts[interCount] = p + fT * r;
508 kE = interPts[interCount] - m_center;
509 fdot = kE.
dot(m_axisDir);
510 if (fdot > (
float)0.0)
512 lambda[interCount] = fT;
517 else if (fC1 / fC2 < 0)
520 interPts[0] = p - (fC1 / fC2) * r;
521 lambda[0] = -(fC1 / fC2);
522 kE = interPts[0] - m_center;
533 else if (
abs(fC1) >= 1e-7)
536 lambda[0] = -(((
float)0.5) * fC0 / fC1);
541 interPts[0] = p + lambda[0] * r;
542 kE = interPts[0] - m_center;
543 fdot = kE.
dot(m_axisDir);
544 if (fdot > (
float)0.0)
553 else if (
abs(fC0) >= 1e-7)
563 lambda[0] = (m_center - p).
dot(r);
564 interPts[0] = m_center;