// Split the polygon into sets of unimonotone chains, and eventually call // TriangulateMonotone() to convert them into triangles. bool Triangulate(Vertex *first, Vertex *last, SkTDArray<SkPoint> *triangles) { DebugPrintf("Triangulate()\n"); Vertex *currentVertex = first; while (!currentVertex->done()) { currentVertex->setDone(true); Vertex *bottomVertex = currentVertex->diagonal(); if (bottomVertex != NULL) { Vertex *saveNext = currentVertex->next(); Vertex *savePrev = bottomVertex->prev(); currentVertex->setNext(bottomVertex); bottomVertex->setPrev(currentVertex); currentVertex->nullifyTrapezoid(); bool success = Triangulate(bottomVertex, currentVertex, triangles); currentVertex->setDone(false); bottomVertex->setDone(false); currentVertex->setNext(saveNext); bottomVertex->setPrev(savePrev); bottomVertex->setNext(currentVertex); currentVertex->setPrev(bottomVertex); return Triangulate(currentVertex, bottomVertex, triangles) && success; } else { currentVertex = currentVertex->next(); } } return TriangulateMonotone(first, last, triangles); }
//Look at the GJK_EPA.h header file for documentation and instructions bool SteerLib::GJK_EPA::intersect(float& return_penetration_depth, Util::Vector& return_penetration_vector, const std::vector<Util::Vector>& _shapeA, const std::vector<Util::Vector>& _shapeB) { if (CONCAVE_POLYGONS) return Triangulate(_shapeA, _shapeB); std::vector<Util::Vector> _simplex; bool colliding; colliding = Triangulate(_shapeA, _shapeB); if (colliding) { EPA(return_penetration_depth, return_penetration_vector, _simplex, _shapeA, _shapeB); return true; } else { return_penetration_depth = 0; return_penetration_vector.zero(); return false; } // To make compiler happy return false; }
/// returns triangle count /// Any invalid vectors are ignored (they are delimiters for multiple polygons) int CreateDelaunayTriangulation( cpVect *verts, int n_verts, cpVect *extraPoints, int pointCount, cpVect *triangles) { int triangleCount; XYZ *p = new XYZ[n_verts + pointCount + 3]; int count = 0; int i; for(i=0;i<n_verts;++i) { //if (verts[i].IsValid()) { p[count].x = verts[i].x; p[count].y = verts[i].y; ++count; //} } for (;i<n_verts+pointCount;++i,++count) { p[count].x = extraPoints[i-n_verts].x; p[count].y = extraPoints[i-n_verts].y; } ITRIANGLE *v = new ITRIANGLE[3 * (pointCount + n_verts)]; qsort(p, count, sizeof(XYZ), XYZCompare); Triangulate(count, p, v, triangleCount); for (int i=0;i<triangleCount;i++) { triangles[3*i] = cpv(p[v[i].p1].x,p[v[i].p1].y); triangles[3*i+1] = cpv(p[v[i].p2].x, p[v[i].p2].y); triangles[3*i+2] = cpv(p[v[i].p3].x, p[v[i].p3].y); } delete[] p; delete[] v; return triangleCount; }
void Microphone::setPrecision (int prec) { precision = prec; delete [] micParts; micParts = new LPMESH3D[PARTS_NUM]; Triangulate(); }
void SQMAlgorithm::triangulateOneRings2() { deque<SQMNode*> queue; if (root != NULL) queue.push_back(root); while (!queue.empty()) { SQMNode *node = queue.front(); SQMNode *cycleNode = node->getCycleNode(); queue.pop_front(); if (node->getSQMNodeType() == SQMCycleLeaf && cycleNode != NULL) { //project stuff glm::vec3 normal = glm::normalize(cycleNode->getPosition_glm() - node->getPosition_glm()); glm::vec3 origin = (cycleNode->getPosition_glm() + node->getPosition_glm())* 0.5f; node->projectOnPlaneRotateAndScale(mesh, origin, normal); cycleNode->projectOnPlaneRotateAndScale(mesh, origin, normal); //triangulate stuff vector<glm::vec3> *nodePoints = node->getCyclePoints(); vector<glm::vec3> *cyclePoints = cycleNode->getCyclePoints(); vector<glm::vec3> points; points.insert(points.end(), (*nodePoints).begin(), (*nodePoints).end()); points.insert(points.end(), (*cyclePoints).begin(), (*cyclePoints).end()); vector<glm::ivec3> triangles; Triangulate(points, triangles); //add triangles to mesh addTrianglesToMesh(node, cycleNode, triangles, (*nodePoints).size()); } for (int i = 0; i < node->getNodes()->size(); i++) { queue.push_back((*node->getNodes())[i]); } } }
int ofxDelaunay::triangulate(){ int nv = vertices.size(); if (nv < 1) return 0; // crashes if try to triangulate 0 points //add 3 emptly slots, required by the Triangulate call vertices.push_back(XYZ()); vertices.push_back(XYZ()); vertices.push_back(XYZ()); //allocate space for triangle indices triangles.resize(3*nv); int ntri; qsort( &vertices[0], vertices.size()-3, sizeof( XYZ ), XYZCompare ); Triangulate( nv, &vertices[0], &triangles[0], ntri ); // copy triangle data to ofxDelaunayTriangle. triangleMesh.clear(); //copy vertices for (int i = 0; i < nv; i++){ triangleMesh.addVertex(ofVec3f(vertices[i].x,vertices[i].y,vertices[i].z)); } //copy triagles for(int i = 0; i < ntri; i++){ triangleMesh.addIndex(triangles[ i ].p1); triangleMesh.addIndex(triangles[ i ].p2); triangleMesh.addIndex(triangles[ i ].p3); } return ntri; }
int ofxDelaunay::triangulate(vector<int> *indices ){ if(vertices.size() < 3){return NULL;} // make clone not to destroy vertices vector<XYZI> verticesTemp; if(indices!=nullptr){ verticesTemp.resize(indices->size()); int j = 0; for (auto & i:*indices){ verticesTemp[j] = vertices[i]; j++; } } else{verticesTemp=vertices;} qsort( &verticesTemp[0], verticesTemp.size(), sizeof( XYZI ), XYZICompare ); int nv = verticesTemp.size(); //vertices required for Triangulate vector<XYZ> verticesXYZ(nv); //copy XYZIs to XYZ for (int i = 0; i < nv; i++) { XYZ v; verticesXYZ[i].x = verticesTemp.at(i).x; verticesXYZ[i].y = verticesTemp.at(i).y; verticesXYZ[i].z = verticesTemp.at(i).z; } //add 3 emptly slots, required by the Triangulate call verticesXYZ.push_back(XYZ()); verticesXYZ.push_back(XYZ()); verticesXYZ.push_back(XYZ()); //allocate space for triangle indices triangles.resize(3*nv); Triangulate( nv, &verticesXYZ[0], &triangles[0], ntri ); //copy triangle data to ofxDelaunayTriangle. triangleMesh.clear(); triangleMesh.setMode(OF_PRIMITIVE_TRIANGLES); //copy vertices for (int i = 0; i < vertices.size(); i++){ triangleMesh.addVertex(ofVec3f(vertices[i].x,vertices[i].y,vertices[i].z)); } //copy triangles for(int i = 0; i < ntri; i++){ triangleMesh.addIndex(verticesTemp.at(triangles[ i ].p1).i); triangleMesh.addIndex(verticesTemp.at(triangles[ i ].p2).i); triangleMesh.addIndex(verticesTemp.at(triangles[ i ].p3).i); } return ntri; }
void MakeDelaunay(const std::vector<float2>& vertexes, std::vector<uint3>& output) { output.clear(); if (vertexes.size() < 3) { return; } int N = (int)vertexes.size(); std::vector<std::pair<float2, int>> vertPairs(N); int index = 0; for (const float2& vert : vertexes) { vertPairs[index] = std::pair<float2, int>(vert, index); index++; } std::sort(vertPairs.begin(), vertPairs.end()); std::vector<float2> tmp; tmp.reserve(vertPairs.size()); for (std::pair<float2, int>& pr : vertPairs) { tmp.push_back(pr.first); } std::vector<int3> cTriangles; Triangulate(tmp, cTriangles); for (int3& triangle : cTriangles) { if (triangle.x < N && triangle.y < N && triangle.z < N) { output.push_back(uint3((uint32_t)vertPairs[triangle.x].second, (uint32_t)vertPairs[triangle.y].second, vertPairs[triangle.z].second)); } } }
Microphone::Microphone(unsigned char red, unsigned char green, unsigned char blue, float br, float bh, float bw, float ur, float uh, float ug, float hi, float hr, float hd, float cr, int prec ) : clsMesh( MSH_MIC, red, green, blue ) { precision = prec; bR = br; bH = bh; bW = bw; uR = ur; uH = uh; uG = ug; hI = hi; hR = hr; hD = hd; cR = cr; tH = bH + uH + uG + hR; micParts = new LPMESH3D[PARTS_NUM]; Triangulate(); }
void SQMAlgorithm::triangulateOneRings() { deque<SQMNode*> queue; if (root != NULL) queue.push_back(root); while (!queue.empty()) { SQMNode *node = queue.front(); SQMNode *cycleNode = node->getCycleNode(); queue.pop_front(); if (node->getSQMNodeType() == SQMCycleLeaf && cycleNode != NULL) { vector<glm::vec3> *nodePoints = node->getCyclePoints(); vector<glm::vec3> *cyclePoints = cycleNode->getCyclePoints(); vector<glm::vec3> points; points.insert(points.end(), (*nodePoints).begin(), (*nodePoints).end()); points.insert(points.end(), (*cyclePoints).begin(), (*cyclePoints).end()); vector<glm::ivec3> triangles; Triangulate(points, triangles); addTrianglesToMesh(node, cycleNode, triangles, (*nodePoints).size()); } for (int i = 0; i < node->getNodes()->size(); i++) { queue.push_back((*node->getNodes())[i]); } } }
vec Polygon::FastRandomPointInside(LCG &rng) const { TriangleArray tris = Triangulate(); if (tris.empty()) return vec::nan; int i = rng.Int(0, (int)tris.size()-1); return TRIANGLE(tris[i]).RandomPointInside(rng); }
bool IsExtrinsicsPossible(const matf & P2, const TrackedPoint & point) { matf P1(3,4,0.0f); //TODO do not recreate each call P1(0,0) = P1(1,1) = P1(2,2) = 1.0f; matf p3d = Triangulate(P1, P2, point); //return p3d(2,0) >= 0; return IsInFront(P1, p3d) && IsInFront(P2, p3d); //TODO IsInFront(P1 ...) is trivial, since P1 is identity }
main() { ReadVertices(); PrintVertices(); printf("%%Area of polygon = %g\n", 0.5 * AreaPoly2() ); Triangulate(); printf("showpage\n%%%%EOF\n"); }
void CIdentityCube::Update(float) { if (m_isDirty) { Triangulate(); m_isDirty = false; } }
float3 Polygon::FastRandomPointInside(LCG &rng) const { std::vector<Triangle> tris = Triangulate(); if (tris.empty()) return float3::nan; int i = rng.Int(0, (int)tris.size()-1); return tris[i].RandomPointInside(rng); }
void CacheGeometryHandler::Render() { if(Obj!=NULL){ if(boolTriangulated==false) Triangulate(); Renderer->Render(Triangulator->getNumberOfPoints(),Triangulator->getNumberOfTriangles(),Triangulator->getTriangleVertices(),Triangulator->getTriangleFaces()); }else if(ObjComp!=NULL){ Renderer->Render(ObjComp); } }
int ofxDelaunay::triangulate(){ if(vertices.size() < 3){ return NULL; } int nv = vertices.size(); // make clone not to destroy vertices vector<XYZI> verticesTemp = vertices; qsort( &verticesTemp[0], verticesTemp.size(), sizeof( XYZI ), XYZICompare ); //vertices required for Triangulate vector<XYZ> verticesXYZ; //copy XYZIs to XYZ for (int i = 0; i < nv; i++) { XYZ v; v.x = verticesTemp.at(i).x; v.y = verticesTemp.at(i).y; v.z = verticesTemp.at(i).z; verticesXYZ.push_back(v); } //add 3 emptly slots, required by the Triangulate call verticesXYZ.push_back(XYZ()); verticesXYZ.push_back(XYZ()); verticesXYZ.push_back(XYZ()); //allocate space for triangle indices triangles.resize(3*nv); Triangulate( nv, &verticesXYZ[0], &triangles[0], ntri ); //copy triangle data to ofxDelaunayTriangle. triangleMesh.clear(); triangleMesh.setMode(OF_PRIMITIVE_TRIANGLES); //copy vertices for (int i = 0; i < nv; i++){ triangleMesh.addVertex(ofVec3f(vertices[i].x,vertices[i].y,vertices[i].z)); } //copy triangles for(int i = 0; i < ntri; i++){ triangleMesh.addIndex(verticesTemp.at(triangles[ i ].p1).i); triangleMesh.addIndex(verticesTemp.at(triangles[ i ].p2).i); triangleMesh.addIndex(verticesTemp.at(triangles[ i ].p3).i); } //erase the last three triangles (missing code from original) vertices.erase(vertices.end()-1); vertices.erase(vertices.end()-1); vertices.erase(vertices.end()-1); return ntri; }
bool Polygon::Intersects(const Capsule &capsule) const { ///@todo Optimize. std::vector<Triangle> tris = Triangulate(); for(size_t i = 0; i < tris.size(); ++i) if (tris[i].Intersects(capsule)) return true; return false; }
bool Polygon::Intersects(const Capsule &capsule) const { ///@todo Optimize. TriangleArray tris = Triangulate(); for(size_t i = 0; i < tris.size(); ++i) if (TRIANGLE(tris[i]).Intersects(capsule)) return true; return false; }
int ofxDelaunay::triangulate(){ XYZ *p_Temp = new XYZ[nv + 3]; for (int i = 0; i < nv; i++) p_Temp[i] = p[i]; delete []p; p = p_Temp; v = new ITRIANGLE[3 * nv]; qsort(p, nv, sizeof(XYZ), XYZCompare); Triangulate(nv, p, v, ntri); return ntri; }
matf TriangulateNonLinear(const matf & P1, const matf & P2, const TrackedPoint & p) { matf X(4,1); X(0,0) = p.x1; X(1,0) = p.y1; X(2,0) = p.x2; X(3,0) = p.y2; DistTriangulateNL dtnl(P1, P2); matf a_; LM(X, Triangulate(P1, P2, p), dtnl, a_); return a_; }
void UPaperSprite::BuildCustomCollisionData() { // Rebuild the runtime geometry TArray<FVector2D> CollisionData; Triangulate(CollisionGeometry, CollisionData); // Adjust the collision data to be relative to the pivot for (int32 PointIndex = 0; PointIndex < CollisionData.Num(); ++PointIndex) { FVector2D& Point = CollisionData[PointIndex]; Point = ConvertTextureSpaceToPivotSpace(Point); } // Bake it to the runtime structure switch (SpriteCollisionDomain) { case ESpriteCollisionMode::Use3DPhysics: { check(BodySetup3D); BodySetup3D->AggGeom.EmptyElements(); //@TODO: Observe if the custom data is really a hand-edited bounding box, and generate box geom instead of convex geom! const FVector HalfThicknessVector = PaperAxisZ * 0.5f * CollisionThickness; //@TODO: Use this guy instead: DecomposeMeshToHulls //@TODO: Merge triangles that are convex together! int32 RunningIndex = 0; for (int32 TriIndex = 0; TriIndex < CollisionData.Num() / 3; ++TriIndex) { FKConvexElem& ConvexTri = *new (BodySetup3D->AggGeom.ConvexElems) FKConvexElem(); ConvexTri.VertexData.Empty(6); for (int32 Index = 0; Index < 3; ++Index) { const FVector2D& Pos2D = CollisionData[RunningIndex++]; const FVector Pos3D = (PaperAxisX * Pos2D.X) + (PaperAxisY * Pos2D.X); new (ConvexTri.VertexData) FVector(Pos3D - HalfThicknessVector); new (ConvexTri.VertexData) FVector(Pos3D + HalfThicknessVector); } ConvexTri.UpdateElemBox(); } BodySetup3D->InvalidatePhysicsData(); BodySetup3D->CreatePhysicsMeshes(); } break; case ESpriteCollisionMode::Use2DPhysics: break; default: check(false); break; } }
//{CodeReview:Triangulation} void Triangulate(std::vector<Polygon2D_t>& polygons, PolygonWinding winding, std::vector<const FVector2*>& triangles) { std::vector<Polygon2D_t*> polygonsForHierarchy; polygonsForHierarchy.reserve(polygons.size()); for (Polygon2D_t& polygon : polygons) { polygonsForHierarchy.push_back(&polygon); } PolygonHierarchy<Polygon2D_t> polygonHierarchy(polygonsForHierarchy, winding, Vec3D::ZAxis(), EarClipper::EXPERIMENTAL_TOLERANCE); std::queue< const PolygonHierarchy<Polygon2D_t>::Node* > polygonNodesToTriangulate; for (const std::unique_ptr<PolygonHierarchy<Polygon2D_t>::Node>& node : polygonHierarchy.Root()->children) { polygonNodesToTriangulate.push(node.get()); } while (!polygonNodesToTriangulate.empty()) { const PolygonHierarchy<Polygon2D_t>::Node* node = polygonNodesToTriangulate.front(); polygonNodesToTriangulate.pop(); std::size_t numChildren = node->children.size(); if (numChildren == 0) { //The outer polygon is a simple polygon with no nested inner polygons Triangulate(*(node->polygon), triangles); } else { std::vector<const Polygon2D_t*> innerPolygons; innerPolygons.reserve(numChildren); //The outer polygon contains inner polygons for (const std::unique_ptr<PolygonHierarchy<Polygon2D_t>::Node>& child : node->children) { const PolygonHierarchy<Polygon2D_t>::Node* innerNode = child.get(); innerPolygons.push_back(innerNode->polygon); for (const std::unique_ptr<PolygonHierarchy<Polygon2D_t>::Node>& grandChild : innerNode->children) { polygonNodesToTriangulate.push(grandChild.get()); } } EarClipper(*(node->polygon), innerPolygons).Triangulate(triangles); } } }
int* CacheGeometryHandler::getTriangleFaces() { if(Obj!=NULL) { Obj->updateGeometryHandler(); if(boolTriangulated==false) Triangulate(); return Triangulator->getTriangleFaces(); } else { return NULL; } }
int CacheGeometryHandler::NumberOfPoints() { if(Obj!=NULL) { Obj->updateGeometryHandler(); if(boolTriangulated==false) Triangulate(); return Triangulator->getNumberOfPoints(); } else { return 0; } }
bool SkConcaveToTriangles(size_t numPts, const SkPoint pts[], SkTDArray<SkPoint> *triangles) { DebugPrintf("SkConcaveToTriangles()\n"); SkTDArray<Vertex> vertices; vertices.setCount(numPts); if (!ConvertPointsToVertices(numPts, pts, vertices.begin())) return false; triangles->setReserve(numPts); triangles->setCount(0); return Triangulate(vertices.begin(), vertices.end() - 1, triangles); }
void Microphone::setTotalHeight (float h) { tH = h; bH = tH * 0.061f; uH = tH * 0.58436f; uG = tH * 0.02057f; hR = tH * 0.165f; cR = tH * 0.12345679f; delete [] micParts; micParts = new LPMESH3D[PARTS_NUM]; Triangulate(); }
float3 Polygon::ClosestPoint(const float3 &point) const { assume(IsPlanar()); std::vector<Triangle> tris = Triangulate(); float3 closestPt = float3::nan; float closestDist = FLT_MAX; for(size_t i = 0; i < tris.size(); ++i) { float3 pt = tris[i].ClosestPoint(point); float d = pt.DistanceSq(point); if (d < closestDist) { closestPt = pt; closestDist = d; } } return closestPt; }
vec Polygon::ClosestPoint(const vec &point) const { assume(IsPlanar()); TriangleArray tris = Triangulate(); vec closestPt = vec::nan; float closestDist = FLT_MAX; for(size_t i = 0; i < tris.size(); ++i) { vec pt = TRIANGLE(tris[i]).ClosestPoint(point); float d = pt.DistanceSq(point); if (d < closestDist) { closestPt = pt; closestDist = d; } } return closestPt; }
void Sphere::Triangulate(VertexBuffer &vb, int numVertices, bool ccwIsFrontFacing) const { Array<vec> position; Array<vec> normal; Array<float2> uv; position.Resize_unspecified(numVertices); normal.Resize_unspecified(numVertices); uv.Resize_unspecified(numVertices); Triangulate(position.ptr(), normal.ptr(), uv.ptr(), numVertices, ccwIsFrontFacing); int startIndex = vb.AppendVertices(numVertices); for(int i = 0; i < (int)position.size(); ++i) { vb.Set(startIndex+i, VDPosition, POINT_TO_FLOAT4(position[i])); if (vb.Declaration()->TypeOffset(VDNormal) >= 0) vb.Set(startIndex+i, VDNormal, DIR_TO_FLOAT4(normal[i])); if (vb.Declaration()->TypeOffset(VDUV) >= 0) vb.SetFloat2(startIndex+i, VDUV, 0, uv[i]); } }