31 template <
typename Real>
51 ApprCylinder3(
unsigned int numThreads,
unsigned int numThetaSamples,
52 unsigned int numPhiSamples);
74 std::vector<Vector3<Real>>
mX;
78 template <
typename Real>
80 unsigned int numPhiSamples)
89 template <
typename Real>
93 if (numPoints < 6 || !points)
100 cylinder.
radius = (Real)0;
101 cylinder.
height = (Real)0;
102 return std::numeric_limits<Real>::max();
105 mX.resize(numPoints);
110 for (
unsigned int i = 0; i < numPoints; ++i)
112 average += points[i];
115 for (
unsigned int i = 0; i < numPoints; ++i)
117 mX[i] = points[i] - average;
122 Real minRSqr, minError;
147 cylinder.
axis.origin = minPC + average;
148 cylinder.
axis.direction = minW;
151 cylinder.
radius = sqrt(minRSqr);
156 Real tmin = (Real)0, tmax = (Real)0;
157 for (
unsigned int i = 0; i < numPoints; ++i)
159 Real
t =
Dot(cylinder.
axis.direction, points[i] - cylinder.
axis.origin);
160 tmin = std::min(t, tmin);
161 tmax = std::max(t, tmax);
164 cylinder.
axis.origin += ((tmin + tmax) * (Real)0.5) * cylinder.
axis.direction;
165 cylinder.
height = tmax - tmin;
169 template <
typename Real>
173 for (
auto const& X :
mX)
178 std::array<Real, 3> eval;
179 std::array<std::array<Real, 3>, 3> evec;
181 covar(0, 0), covar(0, 1), covar(0, 2), covar(1, 1), covar(1, 2), covar(2, 2),
182 true, +1, eval, evec);
184 return Error(minW, minPC, minRSqr);
187 template <
typename Real>
194 minW = { (Real)0, (Real)0, (Real)1 };
195 Real minError =
Error(minW, minPC, minRSqr);
199 Real phi = jMultiplier *
static_cast<Real
>(j);
200 Real csphi = cos(phi);
201 Real snphi = sin(phi);
204 Real theta = iMultiplier *
static_cast<Real
>(i);
205 Real cstheta = cos(theta);
206 Real sntheta = sin(theta);
210 Real error =
Error(W, PC, rsqr);
211 if (error < minError)
224 template <
typename Real>
231 minW = { (Real)0, (Real)0, (Real)1 };
232 Real minError =
Error(minW, minPC, minRSqr);
251 local[
t].error = std::numeric_limits<Real>::max();
252 local[
t].rsqr = (Real)0;
255 local[
t].imin = numThetaSamplesPerThread *
t;
256 local[
t].imax = numThetaSamplesPerThread * (t + 1);
257 local[
t].jmin = numPhiSamplesPerThread *
t;
258 local[
t].jmax = numPhiSamplesPerThread * (t + 1);
263 std::vector<std::thread> process(mNumThreads);
266 process[
t] = std::thread
268 [
this,
t, iMultiplier, jMultiplier, &local]()
270 for (
unsigned int j = local[
t].jmin; j < local[
t].jmax; ++j)
272 Real phi = jMultiplier *
static_cast<Real
>(j);
273 Real csphi = cos(phi);
274 Real snphi = sin(phi);
275 for (
unsigned int i = local[
t].imin; i < local[
t].imax; ++i)
277 Real theta = iMultiplier *
static_cast<Real
>(i);
278 Real cstheta = cos(theta);
279 Real sntheta = sin(theta);
283 Real error =
Error(W, PC, rsqr);
284 if (error < local[
t].error)
286 local[
t].error = error;
287 local[
t].rsqr = rsqr;
301 if (local[
t].error < minError)
303 minError = local[
t].error;
304 minRSqr = local[
t].rsqr;
313 template <
typename Real>
319 (Real)0, -W[2], W[1],
320 W[2], (Real)0, -W[0],
324 std::vector<Vector3<Real>> Y(
mX.size());
325 std::vector<Real> sqrLength(
mX.size());
329 Real qform = (Real)0;
330 for (
size_t i = 0; i <
mX.size(); ++i)
334 sqrLength[i] =
Dot(projection, projection);
336 B += sqrLength[i] * projection;
337 qform += sqrLength[i];
344 PC = (Ahat * B) / Trace<Real>(Ahat * A);
346 Real error = (Real)0;
348 for (
size_t i = 0; i <
mX.size(); ++i)
350 Real term = sqrLength[i] -
Dot(Y[i], PC) * (Real)2 - qform;
351 error += term * term;
353 rsqr +=
Dot(diff, diff);
unsigned int mNumPhiSamples
Real ComputeMultiThreaded(Vector3< Real > &minPC, Vector3< Real > &minW, Real &minRSqr)
std::vector< Vector3< Real > > mX
Real operator()(unsigned int numPoints, Vector3< Real > const *points, Cylinder3< Real > &cylinder)
Real ComputeUsingCovariance(Vector3< Real > &minPC, Vector3< Real > &minW, Real &minRSqr)
GLfixed GLfixed GLint GLint GLfixed points
unsigned int mNumThetaSamples
ApprCylinder3(unsigned int numThreads, unsigned int numThetaSamples, unsigned int numPhiSamples)
DualQuaternion< Real > Dot(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
Real ComputeSingleThreaded(Vector3< Real > &minPC, Vector3< Real > &minW, Real &minRSqr)
Real Error(Vector3< Real > const &W, Vector3< Real > &PC, Real &rsqr) const
GMatrix< Real > OuterProduct(GVector< Real > const &U, GVector< Real > const &V)