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(); }
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(); }
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; }