Box3<Real> GaussPointsFit3 (int iQuantity, const Vector3<Real>* akPoint)
{
    Box3<Real> kBox(Vector3<Real>::ZERO,Vector3<Real>::UNIT_X,
        Vector3<Real>::UNIT_Y,Vector3<Real>::UNIT_Z,(Real)1.0,(Real)1.0,
        (Real)1.0);

    // compute the mean of the points
    kBox.Center = akPoint[0];
    int i;
    for (i = 1; i < iQuantity; i++)
    {
        kBox.Center += akPoint[i];
    }
    Real fInvQuantity = ((Real)1.0)/iQuantity;
    kBox.Center *= fInvQuantity;

    // compute the covariance matrix of the points
    Real fSumXX = (Real)0.0, fSumXY = (Real)0.0, fSumXZ = (Real)0.0;
    Real fSumYY = (Real)0.0, fSumYZ = (Real)0.0, fSumZZ = (Real)0.0;
    for (i = 0; i < iQuantity; i++)
    {
        Vector3<Real> kDiff = akPoint[i] - kBox.Center;
        fSumXX += kDiff.X()*kDiff.X();
        fSumXY += kDiff.X()*kDiff.Y();
        fSumXZ += kDiff.X()*kDiff.Z();
        fSumYY += kDiff.Y()*kDiff.Y();
        fSumYZ += kDiff.Y()*kDiff.Z();
        fSumZZ += kDiff.Z()*kDiff.Z();
    }

    fSumXX *= fInvQuantity;
    fSumXY *= fInvQuantity;
    fSumXZ *= fInvQuantity;
    fSumYY *= fInvQuantity;
    fSumYZ *= fInvQuantity;
    fSumZZ *= fInvQuantity;

    // setup the eigensolver
    Eigen<Real> kES(3);
    kES(0,0) = fSumXX;
    kES(0,1) = fSumXY;
    kES(0,2) = fSumXZ;
    kES(1,0) = fSumXY;
    kES(1,1) = fSumYY;
    kES(1,2) = fSumYZ;
    kES(2,0) = fSumXZ;
    kES(2,1) = fSumYZ;
    kES(2,2) = fSumZZ;
    kES.IncrSortEigenStuff3();

    for (i = 0; i < 3; i++)
    {
        kBox.Extent[i] = kES.GetEigenvalue(i);
        kES.GetEigenvector(i,kBox.Axis[i]);
    }

    return kBox;
}
Esempio n. 2
0
Line2<Real> OrthogonalLineFit2 (int iQuantity, const Vector2<Real>* akPoint)
{
    Line2<Real> kLine(Vector2<Real>::ZERO,Vector2<Real>::ZERO);

    // compute the mean of the points
    kLine.Origin = akPoint[0];
    int i;
    for (i = 1; i < iQuantity; i++)
    {
        kLine.Origin += akPoint[i];
    }
    Real fInvQuantity = ((Real)1.0)/iQuantity;
    kLine.Origin *= fInvQuantity;

    // compute the covariance matrix of the points
    Real fSumXX = (Real)0.0, fSumXY = (Real)0.0, fSumYY = (Real)0.0;
    for (i = 0; i < iQuantity; i++) 
    {
        Vector2<Real> kDiff = akPoint[i] - kLine.Origin;
        fSumXX += kDiff.X()*kDiff.X();
        fSumXY += kDiff.X()*kDiff.Y();
        fSumYY += kDiff.Y()*kDiff.Y();
    }

    fSumXX *= fInvQuantity;
    fSumXY *= fInvQuantity;
    fSumYY *= fInvQuantity;

    // set up the eigensolver
    Eigen<Real> kES(2);
    kES(0,0) = fSumYY;
    kES(0,1) = -fSumXY;
    kES(1,0) = -fSumXY;
    kES(1,1) = fSumXX;

    // compute eigenstuff, smallest eigenvalue is in last position
    kES.DecrSortEigenStuff2();

    // unit-length direction for best-fit line
    kES.GetEigenvector(1,kLine.Direction);

    return kLine;
}
Esempio n. 3
0
Real QuadraticFit2 (int iQuantity, const Vector2<Real>* akPoint,
    Real afCoeff[6])
{
    Eigen<Real> kES(6);
    int iRow, iCol;
    for (iRow = 0; iRow < 6; iRow++)
    {
        for (iCol = 0; iCol < 6; iCol++)
        {
            kES(iRow,iCol) = (Real)0.0;
        }
    }

    for (int i = 0; i < iQuantity; i++)
    {
        Real fX = akPoint[i].X();
        Real fY = akPoint[i].Y();
        Real fX2 = fX*fX;
        Real fY2 = fY*fY;
        Real fXY = fX*fY;
        Real fX3 = fX*fX2;
        Real fXY2 = fX*fY2;
        Real fX2Y = fX*fXY;
        Real fY3 = fY*fY2;
        Real fX4 = fX*fX3;
        Real fX2Y2 = fX*fXY2;
        Real fX3Y = fX*fX2Y;
        Real fY4 = fY*fY3;
        Real fXY3 = fX*fY3;

        kES(0,1) += fX;
        kES(0,2) += fY;
        kES(0,3) += fX2;
        kES(0,4) += fY2;
        kES(0,5) += fXY;
        kES(1,3) += fX3;
        kES(1,4) += fXY2;
        kES(1,5) += fX2Y;
        kES(2,4) += fY3;
        kES(3,3) += fX4;
        kES(3,4) += fX2Y2;
        kES(3,5) += fX3Y;
        kES(4,4) += fY4;
        kES(4,5) += fXY3;
    }

    kES(0,0) = (Real)iQuantity;
    kES(1,1) = kES(0,3);
    kES(1,2) = kES(0,5);
    kES(2,2) = kES(0,4);
    kES(2,3) = kES(1,5);
    kES(2,5) = kES(1,4);
    kES(5,5) = kES(3,4);

    for (iRow = 0; iRow < 6; iRow++)
    {
        for (iCol = 0; iCol < iRow; iCol++)
        {
            kES(iRow,iCol) = kES(iCol,iRow);
        }
    }

    Real fInvQuantity = ((Real)1.0)/(Real)iQuantity;
    for (iRow = 0; iRow < 6; iRow++)
    {
        for (iCol = 0; iCol < 6; iCol++)
        {
            kES(iRow,iCol) *= fInvQuantity;
        }
    }

    kES.IncrSortEigenStuffN();

    GVector<Real> kEVector = kES.GetEigenvector(0);
    size_t uiSize = 6*sizeof(Real);
    System::Memcpy(afCoeff,uiSize,(Real*)kEVector,uiSize);

    // For exact fit, numeric round-off errors may make the minimum
    // eigenvalue just slightly negative.  Return absolute value since
    // application may rely on the return value being nonnegative.
    return Math<Real>::FAbs(kES.GetEigenvalue(0));
}
Esempio n. 4
0
Real QuadraticCircleFit2 (int iQuantity, const Vector2<Real>* akPoint,
    Vector2<Real>& rkCenter, Real& rfRadius)
{
    Eigen<Real> kES(4);
    int iRow, iCol;
    for (iRow = 0; iRow < 4; iRow++)
    {
        for (iCol = 0; iCol < 4; iCol++)
        {
            kES(iRow,iCol) = (Real)0.0;
        }
    }

    for (int i = 0; i < iQuantity; i++)
    {
        Real fX = akPoint[i].X();
        Real fY = akPoint[i].Y();
        Real fX2 = fX*fX;
        Real fY2 = fY*fY;
        Real fXY = fX*fY;
        Real fR2 = fX2+fY2;
        Real fXR2 = fX*fR2;
        Real fYR2 = fY*fR2;
        Real fR4 = fR2*fR2;

        kES(0,1) += fX;
        kES(0,2) += fY;
        kES(0,3) += fR2;
        kES(1,1) += fX2;
        kES(1,2) += fXY;
        kES(1,3) += fXR2;
        kES(2,2) += fY2;
        kES(2,3) += fYR2;
        kES(3,3) += fR4;
    }

    kES(0,0) = (Real)iQuantity;

    for (iRow = 0; iRow < 4; iRow++)
    {
        for (iCol = 0; iCol < iRow; iCol++)
        {
            kES(iRow,iCol) = kES(iCol,iRow);
        }
    }

    Real fInvQuantity = ((Real)1.0)/(Real)iQuantity;
    for (iRow = 0; iRow < 4; iRow++)
    {
        for (iCol = 0; iCol < 4; iCol++)
        {
            kES(iRow,iCol) *= fInvQuantity;
        }
    }

    kES.IncrSortEigenStuffN();

    GVector<Real> kEVector = kES.GetEigenvector(0);
    Real fInv = ((Real)1.0)/kEVector[3];  // beware zero divide
    Real afCoeff[3];
    for (iRow = 0; iRow < 3; iRow++)
    {
        afCoeff[iRow] = fInv*kEVector[iRow];
    }

    rkCenter.X() = -((Real)0.5)*afCoeff[1];
    rkCenter.Y() = -((Real)0.5)*afCoeff[2];
    rfRadius = Math<Real>::Sqrt(Math<Real>::FAbs(rkCenter.X()*rkCenter.X() +
        rkCenter.Y()*rkCenter.Y() - afCoeff[0]));

    // For exact fit, numeric round-off errors may make the minimum
    // eigenvalue just slightly negative.  Return absolute value since
    // application may rely on the return value being nonnegative.
    return Math<Real>::FAbs(kES.GetEigenvalue(0));
}
Esempio n. 5
0
		Vector4T<PrimitiveType> PlaneFit(const Vector3T<PrimitiveType> pts[], size_t ptCount)
	{
			/*
					Given a set of points in 3 space, find a plane that best matches them, using least
					squares regression.

					The algorithm and base implementation here is from Geometric Tools, LLC
					Copyright (c) 1998-2010
					Distributed under the Boost Software License, Version 1.0.
					http://www.boost.org/LICENSE_1_0.txt
					http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt

					see http://www.geometrictools.com/Documentation/LeastSquaresFitting.pdf for a
					description. Note that this is the orthogonal regression version. There is also
					a version for dealing with points of the form (x,y, f(x,y)) -- this is less
					general (as it seeks to minimize delta z), but may provide suitable results in
					most cases.
			*/


		// compute the mean of the points
		auto kOrigin = Zero<Vector3T<PrimitiveType>>();
		for (size_t i = 0; i < ptCount; i++)
			kOrigin += pts[i];
		PrimitiveType reciprocalCount = ((PrimitiveType)1.0)/ptCount;
		kOrigin *= reciprocalCount;

		// compute sums of products
		PrimitiveType fSumXX = (PrimitiveType)0.0, fSumXY = (PrimitiveType)0.0, fSumXZ = (PrimitiveType)0.0;
		PrimitiveType fSumYY = (PrimitiveType)0.0, fSumYZ = (PrimitiveType)0.0, fSumZZ = (PrimitiveType)0.0;
		for (size_t i = 0; i < ptCount; i++) 
		{
			auto kDiff = pts[i] - kOrigin;
			fSumXX += kDiff[0]*kDiff[0];
			fSumXY += kDiff[0]*kDiff[1];
			fSumXZ += kDiff[0]*kDiff[2];
			fSumYY += kDiff[1]*kDiff[1];
			fSumYZ += kDiff[1]*kDiff[2];
			fSumZZ += kDiff[2]*kDiff[2];
		}

		fSumXX *= reciprocalCount;
		fSumXY *= reciprocalCount;
		fSumXZ *= reciprocalCount;
		fSumYY *= reciprocalCount;
		fSumYZ *= reciprocalCount;
		fSumZZ *= reciprocalCount;

		// setup the eigensolver
		Eigen<PrimitiveType> kES(3);
		kES(0,0) = fSumXX;
		kES(0,1) = fSumXY;
		kES(0,2) = fSumXZ;
		kES(1,0) = fSumXY;
		kES(1,1) = fSumYY;
		kES(1,2) = fSumYZ;
		kES(2,0) = fSumXZ;
		kES(2,1) = fSumYZ;
		kES(2,2) = fSumZZ;

		// compute eigenstuff, smallest eigenvalue is in last position
		kES.DecrSortEigenStuff3();

		// get plane normal
		Vector3T<PrimitiveType> kNormal;
		kES.GetEigenvector(2,kNormal);

		// the minimum energy
		return Expand( kNormal, -Dot( kNormal, kOrigin ) );
	}