1 #ifndef CYLINDER_HEADER
2 #define CYLINDER_HEADER
40 bool Init(
const Vec3f& axisDir,
const Vec3f& axisPos,
float radius);
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* normal)
const;
47 inline float DistanceAndNormal(
const Vec3f& p,
Vec3f* normal)
const;
48 inline float SignedDistance(
const Vec3f& p)
const;
54 const Vec3f& AxisDirection()
const;
55 Vec3f& AxisDirection();
56 const Vec3f& AxisPosition()
const;
57 Vec3f& AxisPosition();
58 const Vec3f AngularDirection()
const;
59 void RotateAngularDirection(
float radians);
63 template <
class IteratorT>
64 bool LeastSquaresFit(IteratorT begin, IteratorT end);
71 return LeastSquaresFit(
pc, begin, end);
77 void Serialize(
bool binary, std::ostream* o)
const;
78 static size_t SerializedSize();
79 void Serialize(FILE* o)
const;
80 void Serialize(
float* array)
const;
81 static size_t SerializedFloatSize();
83 void Transform(
float scale,
const Vec3f& translate);
86 Intersect(
const Vec3f& p,
const Vec3f& r,
float* first,
float* second)
const;
89 template <
class WeightT>
90 class LevMarCylinder :
public WeightT
98 typedef float ScalarType;
100 template <
class IteratorT>
102 Chi(
const ScalarType* params,
106 ScalarType* temp)
const
109 int size = end - begin;
110 #pragma omp parallel for schedule(static) reduction(+ : chi)
111 for (
int idx = 0; idx < size; ++idx)
114 for (
unsigned int j = 0; j < 3; ++j)
116 s[j] = begin[idx][j] - params[j];
118 ScalarType u = params[5] *
s[1] - params[4] *
s[2];
120 ScalarType
v = params[3] *
s[2] - params[5] *
s[0];
122 v = params[4] *
s[0] - params[3] *
s[1];
125 chi += (
values[idx] = WeightT::Weigh(temp[idx] - params[6])) *
values[idx];
130 template <
class IteratorT>
132 Derivatives(
const ScalarType* params,
136 const ScalarType* temp,
137 ScalarType* matrix)
const
139 int size = end - begin;
140 #pragma omp parallel for schedule(static)
141 for (
int idx = 0; idx < size; ++idx)
144 for (
unsigned int j = 0; j < 3; ++j)
146 s[j] = begin[idx][j] - params[j];
148 ScalarType g =
s[0] * begin[idx][0] +
s[1] * begin[idx][1] +
s[2] * begin[idx][2];
149 if (temp[idx] < 1e-6)
151 matrix[idx * NumParams + 0] =
std::sqrt(1 - params[3] * params[3]);
152 matrix[idx * NumParams + 1] =
std::sqrt(1 - params[4] * params[4]);
153 matrix[idx * NumParams + 2] =
std::sqrt(1 - params[5] * params[5]);
157 matrix[idx * NumParams + 0] = (params[3] * g -
s[0]) / temp[idx];
158 matrix[idx * NumParams + 1] = (params[4] * g -
s[1]) / temp[idx];
159 matrix[idx * NumParams + 2] = (params[5] * g -
s[2]) / temp[idx];
161 matrix[idx * NumParams + 3] = g * matrix[idx * NumParams + 0];
162 matrix[idx * NumParams + 4] = g * matrix[idx * NumParams + 1];
163 matrix[idx * NumParams + 5] = g * matrix[idx * NumParams + 2];
164 matrix[idx * NumParams + 6] = -1;
165 WeightT::template DerivWeigh<NumParams>(temp[idx] - params[6],
166 matrix + idx * NumParams);
171 Normalize(ScalarType* params)
const
174 std::sqrt(params[3] * params[3] + params[4] * params[4] + params[5] * params[5]);
175 for (
unsigned int i = 3; i < 6; ++i)
180 float lambda = -(params[0] * params[3] + params[1] * params[4] + params[2] * params[5]);
181 for (
unsigned int i = 0; i < 3; ++i)
183 params[i] = params[i] + lambda * params[i + 3];
193 float m_angularRotatedRadians;
199 Vec3f diff = p - m_axisPos;
200 float lambda = m_axisDir.
dot(diff);
201 float axisDist = (diff - lambda * m_axisDir).length();
202 return abs(axisDist - m_radius);
208 Vec3f diff = p - m_axisPos;
209 float lambda = m_axisDir.
dot(diff);
210 *normal = diff - lambda * m_axisDir;
217 Vec3f diff = p - m_axisPos;
218 float lambda = m_axisDir.
dot(diff);
219 *normal = diff - lambda * m_axisDir;
220 float axisDist = normal->
length();
225 return abs(axisDist - m_radius);
231 Vec3f diff = p - m_axisPos;
232 float lambda = m_axisDir.
dot(diff);
233 float axisDist = (diff - lambda * m_axisDir).length();
234 return axisDist - m_radius;
237 template <
class IteratorT>
242 for (
size_t i = 0; i < 3; ++i)
244 param[i] = m_axisPos[i];
246 for (
size_t i = 0; i < 3; ++i)
248 param[i + 3] = m_axisDir[i];
251 LevMarCylinder<LevMarLSWeight> levMarCylinder;
252 if (!
LevMar(begin, end, levMarCylinder, param))
256 for (
size_t i = 0; i < 3; ++i)
258 m_axisPos[i] = param[i];
260 for (
size_t i = 0; i < 3; ++i)
262 m_axisDir[i] = param[i + 3];
265 m_hcs.FromNormal(m_axisDir);
266 m_angularRotatedRadians = 0;
280 float fRSqr = m_radius * m_radius;
283 Vec3f kDiff = p - m_axisPos;
284 Vec3f kP(kDiff.
dot(m_hcs[0]), kDiff.
dot(m_hcs[1]), m_axisDir.dot(kDiff));
288 float fDz = m_axisDir.dot(r);
290 if (
abs(fDz) >= 1.f - 1e-7f)
299 float fA0, fA1, fA2, fDiscr, fRoot, fInv;
306 fA0 = kP[0] * kP[0] + kP[1] * kP[1] - fRSqr;
307 fA1 = kP[0] * kD[0] + kP[1] * kD[1];
308 fA2 = kD[0] * kD[0] + kD[1] * kD[1];
309 fDiscr = fA1 * fA1 - fA0 * fA2;
315 else if (fDiscr > 1e-7f)
318 fRoot =
sqrt(fDiscr);
320 *first = (-fA1 - fRoot) * fInv;
321 *second = (-fA1 + fRoot) * fInv;