Пример #1
0
ConvexHull3<Real>::ConvexHull3 (int numVertices, Vector3<Real>* vertices,
    Real epsilon, bool owner, Query::Type queryType)
    :
    ConvexHull<Real>(numVertices, epsilon, owner, queryType),
    mLineOrigin(Vector3<Real>::ZERO),
    mLineDirection(Vector3<Real>::ZERO),
    mPlaneOrigin(Vector3<Real>::ZERO)
{
    mVertices = vertices;
    mPlaneDirection[0] = Vector3<Real>::ZERO;
    mPlaneDirection[1] = Vector3<Real>::ZERO;
    mSVertices = 0;
    mQuery = 0;

    typename Vector3<Real>::Information info;
    Vector3<Real>::GetInformation(mNumVertices, mVertices, mEpsilon, info);
    if (info.mDimension == 0)
    {
        // The values of mDimension and mIndices were already initialized by
        // the ConvexHull base class.
        return;
    }

    if (info.mDimension == 1)
    {
        // The set is (nearly) collinear.  The caller is responsible for
        // creating a ConvexHull1 object.
        mDimension = 1;
        mLineOrigin = info.mOrigin;
        mLineDirection = info.mDirection[0];
        return;
    }

    if (info.mDimension == 2)
    {
        // The set is (nearly) coplanar.  The caller is responsible for
        // creating a ConvexHull2 object.
        mDimension = 2;
        mPlaneOrigin = info.mOrigin;
        mPlaneDirection[0] = info.mDirection[0];
        mPlaneDirection[1] = info.mDirection[1];
        return;
    }

    mDimension = 3;

    int i0 = info.mExtreme[0];
    int i1 = info.mExtreme[1];
    int i2 = info.mExtreme[2];
    int i3 = info.mExtreme[3];

    mSVertices = new1<Vector3<Real> >(mNumVertices);
    int i;

    if (queryType != Query::QT_RATIONAL && queryType != Query::QT_FILTERED)
    {
        // Transform the vertices to the cube [0,1]^3.
        Vector3<Real> minValue(info.mMin[0], info.mMin[1], info.mMin[2]);
        Real scale = ((Real)1)/info.mMaxRange;
        for (i = 0; i < mNumVertices; ++i)
        {
            mSVertices[i] = (mVertices[i] - minValue)*scale;
        }

        Real expand;
        if (queryType == Query::QT_INT64)
        {
            // Scale the vertices to the square [0,2^{20}]^2 to allow use of
            // 64-bit integers.
            expand = (Real)(1 << 20);
            mQuery = new0 Query3Int64<Real>(mNumVertices, mSVertices);
        }
        else if (queryType == Query::QT_INTEGER)
        {
            // Scale the vertices to the square [0,2^{24}]^2 to allow use of
            // Integer.
            expand = (Real)(1 << 24);
            mQuery = new0 Query3Integer<Real>(mNumVertices, mSVertices);
        }
        else  // queryType == Query::QT_REAL
        {
            // No scaling for floating point.
            expand = (Real)1;
            mQuery = new0 Query3<Real>(mNumVertices, mSVertices);
        }

        for (i = 0; i < mNumVertices; ++i)
        {
            mSVertices[i] *= expand;
        }
    }
    else
    {
        // No transformation needed for exact rational arithmetic or filtered
        // predicates.
        memcpy(mSVertices, mVertices, mNumVertices*sizeof(Vector3<Real>));

        if (queryType == Query::QT_RATIONAL)
        {
            mQuery = new0 Query3Rational<Real>(mNumVertices, mSVertices);
        }
        else // queryType == Query::QT_FILTERED
        {
            mQuery = new0 Query3Filtered<Real>(mNumVertices, mSVertices,
                mEpsilon);
        }
    }

    Triangle* tri0;
    Triangle* tri1;
    Triangle* tri2;
    Triangle* tri3;

    if (info.mExtremeCCW)
    {
        tri0 = new0 Triangle(i0, i1, i3);
        tri1 = new0 Triangle(i0, i2, i1);
        tri2 = new0 Triangle(i0, i3, i2);
        tri3 = new0 Triangle(i1, i2, i3);
        tri0->AttachTo(tri1, tri3, tri2);
        tri1->AttachTo(tri2, tri3, tri0);
        tri2->AttachTo(tri0, tri3, tri1);
        tri3->AttachTo(tri1, tri2, tri0);
    }
    else
    {
        tri0 = new0 Triangle(i0, i3, i1);
        tri1 = new0 Triangle(i0, i1, i2);
        tri2 = new0 Triangle(i0, i2, i3);
        tri3 = new0 Triangle(i1, i3, i2);
        tri0->AttachTo(tri2, tri3, tri1);
        tri1->AttachTo(tri0, tri3, tri2);
        tri2->AttachTo(tri1, tri3, tri0);
        tri3->AttachTo(tri0, tri2, tri1);
    }

    mHull.clear();
    mHull.insert(tri0);
    mHull.insert(tri1);
    mHull.insert(tri2);
    mHull.insert(tri3);

    for (i = 0; i < mNumVertices; ++i)
    {
        if (!Update(i))
        {
            DeleteHull();
            return;
        }
    }

    ExtractIndices();
}
Пример #2
0
ConvexHull3<Real>::ConvexHull3 (int iVertexQuantity, Vector3<Real>* akVertex,
    Real fEpsilon, bool bOwner, Query::Type eQueryType)
    :
    ConvexHull<Real>(iVertexQuantity,fEpsilon,bOwner,eQueryType),
    m_kLineOrigin(Vector3<Real>::ZERO),
    m_kLineDirection(Vector3<Real>::ZERO),
    m_kPlaneOrigin(Vector3<Real>::ZERO)
{
    assert(akVertex);
    m_akVertex = akVertex;
    m_akPlaneDirection[0] = Vector3<Real>::ZERO;
    m_akPlaneDirection[1] = Vector3<Real>::ZERO;
    m_akSVertex = 0;
    m_pkQuery = 0;

    Mapper3<Real> kMapper(m_iVertexQuantity,m_akVertex,m_fEpsilon);
    if (kMapper.GetDimension() == 0)
    {
        // The values of m_iDimension, m_aiIndex, and m_aiAdjacent were
        // already initialized by the ConvexHull base class.
        return;
    }

    if (kMapper.GetDimension() == 1)
    {
        // The set is (nearly) collinear.  The caller is responsible for
        // creating a ConvexHull1 object.
        m_iDimension = 1;
        m_kLineOrigin = kMapper.GetOrigin();
        m_kLineDirection = kMapper.GetDirection(0);
        return;
    }

    if (kMapper.GetDimension() == 2)
    {
        // The set is (nearly) coplanar.  The caller is responsible for
        // creating a ConvexHull2 object.
        m_iDimension = 2;
        m_kPlaneOrigin = kMapper.GetOrigin();
        m_akPlaneDirection[0] = kMapper.GetDirection(0);
        m_akPlaneDirection[1] = kMapper.GetDirection(1);
        return;
    }

    m_iDimension = 3;

    int i0 = kMapper.GetExtremeIndex(0);
    int i1 = kMapper.GetExtremeIndex(1);
    int i2 = kMapper.GetExtremeIndex(2);
    int i3 = kMapper.GetExtremeIndex(3);

    m_akSVertex = WM4_NEW Vector3<Real>[m_iVertexQuantity];
    int i;

    if (eQueryType != Query::QT_RATIONAL && eQueryType != Query::QT_FILTERED)
    {
        // Transform the vertices to the cube [0,1]^3.
        Vector3<Real> kMin = kMapper.GetMin();
        Real fScale = ((Real)1.0)/kMapper.GetMaxRange();
        for (i = 0; i < m_iVertexQuantity; i++)
        {
            m_akSVertex[i] = (m_akVertex[i] - kMin)*fScale;
        }

        Real fExpand;
        if (eQueryType == Query::QT_INT64)
        {
            // Scale the vertices to the square [0,2^{20}]^2 to allow use of
            // 64-bit integers.
            fExpand = (Real)(1 << 20);
            m_pkQuery = WM4_NEW Query3Int64<Real>(m_iVertexQuantity,
                m_akSVertex);
        }
        else if (eQueryType == Query::QT_INTEGER)
        {
            // Scale the vertices to the square [0,2^{24}]^2 to allow use of
            // TInteger.
            fExpand = (Real)(1 << 24);
            m_pkQuery = WM4_NEW Query3TInteger<Real>(m_iVertexQuantity,
                m_akSVertex);
        }
        else  // eQueryType == Query::QT_REAL
        {
            // No scaling for floating point.
            fExpand = (Real)1.0;
            m_pkQuery = WM4_NEW Query3<Real>(m_iVertexQuantity,m_akSVertex);
        }

        for (i = 0; i < m_iVertexQuantity; i++)
        {
            m_akSVertex[i] *= fExpand;
        }
    }
    else
    {
        // No transformation needed for exact rational arithmetic or filtered
        // predicates.
        size_t uiSize = m_iVertexQuantity*sizeof(Vector3<Real>);
        System::Memcpy(m_akSVertex,uiSize,m_akVertex,uiSize);

        if (eQueryType == Query::QT_RATIONAL)
        {
            m_pkQuery = WM4_NEW Query3TRational<Real>(m_iVertexQuantity,
                m_akSVertex);
        }
        else // eQueryType == Query::QT_FILTERED
        {
            m_pkQuery = WM4_NEW Query3Filtered<Real>(m_iVertexQuantity,
                m_akSVertex,m_fEpsilon);
        }
    }

    Triangle* pkT0;
    Triangle* pkT1;
    Triangle* pkT2;
    Triangle* pkT3;

    if (kMapper.GetExtremeCCW())
    {
        pkT0 = WM4_NEW Triangle(i0,i1,i3);
        pkT1 = WM4_NEW Triangle(i0,i2,i1);
        pkT2 = WM4_NEW Triangle(i0,i3,i2);
        pkT3 = WM4_NEW Triangle(i1,i2,i3);
        pkT0->AttachTo(pkT1,pkT3,pkT2);
        pkT1->AttachTo(pkT2,pkT3,pkT0);
        pkT2->AttachTo(pkT0,pkT3,pkT1);
        pkT3->AttachTo(pkT1,pkT2,pkT0);
    }
    else
    {
        pkT0 = WM4_NEW Triangle(i0,i3,i1);
        pkT1 = WM4_NEW Triangle(i0,i1,i2);
        pkT2 = WM4_NEW Triangle(i0,i2,i3);
        pkT3 = WM4_NEW Triangle(i1,i3,i2);
        pkT0->AttachTo(pkT2,pkT3,pkT1);
        pkT1->AttachTo(pkT0,pkT3,pkT2);
        pkT2->AttachTo(pkT1,pkT3,pkT0);
        pkT3->AttachTo(pkT0,pkT2,pkT1);
    }

    m_kHull.clear();
    m_kHull.insert(pkT0);
    m_kHull.insert(pkT1);
    m_kHull.insert(pkT2);
    m_kHull.insert(pkT3);

    for (i = 0; i < m_iVertexQuantity; i++)
    {
        if (!Update(i))
        {
            DeleteHull();
            return;
        }
    }

    ExtractIndices();
}
Пример #3
0
bool ConvexHull3::computeCH()
{
	std::vector<int> mExtreme;
	bool CCW = getExtremes(mExtreme);

	int i0 = mExtreme[0];
	int i1 = mExtreme[1];
	int i2 = mExtreme[2];
	int i3 = mExtreme[3];

	epsilon = (mPnts[i0]-mPnts[i1]).norm() / (Real)pow(10.0, precision);


	TriFace* tri0;
	TriFace* tri1;
	TriFace* tri2;
	TriFace* tri3;

	if (CCW){
		tri0 = new TriFace(i0, i1, i3);
		tri1 = new TriFace(i0, i2, i1);
		tri2 = new TriFace(i0, i3, i2);
		tri3 = new TriFace(i1, i2, i3);
		tri0->AttachTo(tri1, tri3, tri2);
		tri1->AttachTo(tri2, tri3, tri0);
		tri2->AttachTo(tri0, tri3, tri1);
		tri3->AttachTo(tri1, tri2, tri0);
	}
	else{
		tri0 = new TriFace(i0, i3, i1);
		tri1 = new TriFace(i0, i1, i2);
		tri2 = new TriFace(i0, i2, i3);
		tri3 = new TriFace(i1, i3, i2);
		tri0->AttachTo(tri2, tri3, tri1);
		tri1->AttachTo(tri0, tri3, tri2);
		tri2->AttachTo(tri1, tri3, tri0);
		tri3->AttachTo(tri0, tri2, tri1);
	}

	mHull.clear();
	mHull.insert(tri0);
	mHull.insert(tri1);
	mHull.insert(tri2);
	mHull.insert(tri3);

	for (int i=0;i<mPnts.size();i++)
	{
		if (!Update(i)){
			DeleteHull();
			return true;
		}

		if(mPnts.size() == 0)
			return false;
	}

	ExtractIndices();

	isReady = true;

	return true;
}