CylinderFit3<Real>::CylinderFit3 (int numPoints, const Vector3<Real>* points, Vector3<Real>& center, Vector3<Real>& axis, Real& radius, Real& height, bool inputsAreInitialGuess) { Real invRSqr = (Real)1; if (!inputsAreInitialGuess) { // Find the least-squares line that fits the data and use it as an // initial guess for the cylinder axis. Line3<Real> line = OrthogonalLineFit3(numPoints, points); center = line.Origin; axis = line.Direction; } mError = Math<Real>::MAX_REAL; const int iMax = 8; int i; for (i = 0; i < iMax; ++i) { mError = UpdateInvRSqr(numPoints, points, center, axis, invRSqr); mError = UpdateDirection(numPoints, points, center, axis, invRSqr); mError = UpdateCenter(numPoints, points, center, axis, invRSqr); } // Compute the radius. radius = Math<Real>::InvSqrt(invRSqr); // Project points onto fitted axis to determine extent of cylinder along // the axis. Real tMin = axis.Dot(points[0] - center); Real tMax = tMin; for (i = 1; i < numPoints; ++i) { Real t = axis.Dot(points[i] - center); if (t < tMin) { tMin = t; } else if (t > tMax) { tMax = t; } } // Compute the height. Adjust the center to point that projects to // midpoint of extent. height = tMax - tMin; center += (((Real)0.5)*(tMin + tMax))*axis; }
CylinderFit3<Real>::CylinderFit3 (int iQuantity, const Vector3<Real>* akPoint, Vector3<Real>& rkC, Vector3<Real>& rkU, Real& rfR, Real& rfH, bool bInputsAreInitialGuess) { Real fInvRSqr = (Real)1.0; if (!bInputsAreInitialGuess) { // Find the least-squares line that fits the data and use it as an // initial guess for the cylinder axis. Line3<Real> kLine = OrthogonalLineFit3(iQuantity,akPoint); rkC = kLine.Origin; rkU = kLine.Direction; } m_fError = Math<Real>::MAX_REAL; const int iMax = 8; int i; for (i = 0; i < iMax; i++) { m_fError = UpdateInvRSqr(iQuantity,akPoint,rkC,rkU,fInvRSqr); m_fError = UpdateDirection(iQuantity,akPoint,rkC,rkU,fInvRSqr); m_fError = UpdateCenter(iQuantity,akPoint,rkC,rkU,fInvRSqr); } // Compute the radius. rfR = Math<Real>::InvSqrt(fInvRSqr); // Project points onto fitted axis to determine extent of cylinder along // the axis. Real fTMin = rkU.Dot(akPoint[0]-rkC), fTMax = fTMin; for (i = 1; i < iQuantity; i++) { Real fT = rkU.Dot(akPoint[i]-rkC); if (fT < fTMin) { fTMin = fT; } else if (fT > fTMax) { fTMax = fT; } } // Compute the height. Adjust the center to point that projects to // midpoint of extent. rfH = fTMax - fTMin; rkC += ((Real)0.5)*(fTMin+fTMax)*rkU; }