int main() { RadixSort sorter; sorter.readList(); sorter.sort(); cout << "Output:\n"; sorter.printArray(); return 0; }
void RadixSortTests::testFloatList() { std::list<float> container; FloatSortFunctor func; RadixSort<std::list<float>, float, float> sorter; for (int i = 0; i < 1000; ++i) { container.push_back((float)Math::RangeRandom(-1e10, 1e10)); } sorter.sort(container, func); std::list<float>::iterator v = container.begin(); float lastValue = *v++; for (;v != container.end(); ++v) { CPPUNIT_ASSERT(*v >= lastValue); lastValue = *v; } }
void RadixSortTests::testIntVector() { std::vector<int> container; IntSortFunctor func; RadixSort<std::vector<int>, int, int> sorter; for (int i = 0; i < 1000; ++i) { container.push_back((int)Math::RangeRandom(-1e10, 1e10)); } sorter.sort(container, func); std::vector<int>::iterator v = container.begin(); int lastValue = *v++; for (;v != container.end(); ++v) { CPPUNIT_ASSERT(*v >= lastValue); lastValue = *v; } }
void RadixSortTests::testUnsignedIntList() { std::list<unsigned int> container; UnsignedIntSortFunctor func; RadixSort<std::list<unsigned int>, unsigned int, unsigned int> sorter; for (int i = 0; i < 1000; ++i) { container.push_back((unsigned int)Math::RangeRandom(0, 1e10)); } sorter.sort(container, func); std::list<unsigned int>::iterator v = container.begin(); unsigned int lastValue = *v++; for (;v != container.end(); ++v) { CPPUNIT_ASSERT(*v >= lastValue); lastValue = *v; } }
// Compute the convex hull using Graham Scan. void nv::convexHull(const Array<Vector2> & input, Array<Vector2> & output, float epsilon/*=0*/) { const uint inputCount = input.count(); Array<float> coords; coords.resize(inputCount); for (uint i = 0; i < inputCount; i++) { coords[i] = input[i].x; } RadixSort radix; radix.sort(coords); const uint * ranks = radix.ranks(); Array<Vector2> top(inputCount); Array<Vector2> bottom(inputCount); Vector2 P = input[ranks[0]]; Vector2 Q = input[ranks[inputCount-1]]; float topy = max(P.y, Q.y); float boty = min(P.y, Q.y); for (uint i = 0; i < inputCount; i++) { Vector2 p = input[ranks[i]]; if (p.y >= boty) top.append(p); } for (uint i = 0; i < inputCount; i++) { Vector2 p = input[ranks[inputCount-1-i]]; if (p.y <= topy) bottom.append(p); } // Filter top list. output.clear(); output.append(top[0]); output.append(top[1]); for (uint i = 2; i < top.count(); ) { Vector2 a = output[output.count()-2]; Vector2 b = output[output.count()-1]; Vector2 c = top[i]; float area = triangleArea(a, b, c); if (area >= -epsilon) { output.popBack(); } if (area < -epsilon || output.count() == 1) { output.append(c); i++; } } uint top_count = output.count(); output.append(bottom[1]); // Filter bottom list. for (uint i = 2; i < bottom.count(); ) { Vector2 a = output[output.count()-2]; Vector2 b = output[output.count()-1]; Vector2 c = bottom[i]; float area = triangleArea(a, b, c); if (area >= -epsilon) { output.popBack(); } if (area < -epsilon || output.count() == top_count) { output.append(c); i++; } } // Remove duplicate element. nvDebugCheck(output.front() == output.back()); output.popBack(); }
void FaceOneRing::initVertices() { const uint edgeCount = m_face->edgeCount(); m_vertexArray.reserve(16); // Add face vertices. for (HalfEdge::Face::ConstEdgeIterator it(m_firstEdge); !it.isDone(); it.advance()) { const HalfEdge::Edge * edge = it.current(); m_vertexArray.append(edge->from()); } // @@ Add support for non manifold surfaces! // The fix: // - not all colocals should point to the same edge. // - multiple colocals could belong to different boundaries, make sure they point to the right one. // @@ When the face neighborhood wraps that could result in overlapping stencils. // Add surronding vertices. for (HalfEdge::Face::ConstEdgeIterator it(m_firstEdge); !it.isDone(); it.advance()) { const HalfEdge::Edge * firstEdge = it.current(); const HalfEdge::Vertex * vertex = firstEdge->from(); const uint valence = vertex->valence(); uint i = 0; // Traverse edges around vertex for (HalfEdge::Vertex::ReverseConstEdgeIterator eit(firstEdge); !eit.isDone(); eit.advance(), i++) { const HalfEdge::Edge * edge = eit.current(); nvCheck(edge->from()->pos() == vertex->pos()); appendVertex(edge->to()); if (edge->face() != NULL) { appendVertex(edge->next()->to()); } } nvDebugCheck(i == valence); } const uint vertexCount = m_vertexArray.count(); // @@ You can only sort by id when the vertices do not have colocals. #if 0 // Sort vertices by id. Create index array per patch. Array<uint> vertexIdArray; vertexIdArray.resize(vertexCount); for (uint v = 0; v < vertexCount; v++) { vertexIdArray[v] = m_vertexArray[v]->id(); } RadixSort radix; radix.sort(vertexIdArray); #else // Sort vertices lexycographically. Create index array per patch. Array<float> vertexXArray; Array<float> vertexYArray; Array<float> vertexZArray; vertexXArray.resize(vertexCount); vertexYArray.resize(vertexCount); vertexZArray.resize(vertexCount); for (uint v = 0; v < vertexCount; v++) { vertexXArray[v] = m_vertexArray[v]->pos().x(); vertexYArray[v] = m_vertexArray[v]->pos().y(); vertexZArray[v] = m_vertexArray[v]->pos().z(); } RadixSort radix; radix.sort(vertexXArray).sort(vertexYArray).sort(vertexZArray); #endif m_vertexIndexArray.resize(vertexCount); const uint * indices = radix.ranks(); for (uint v = 0; v < vertexCount; v++) { m_vertexIndexArray[v] = indices[v]; } }