// 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);
}
Ejemplo n.º 2
0
//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;
}	
Ejemplo n.º 4
0
void Microphone::setPrecision	(int prec) {
	precision = prec;

	delete [] micParts;
	micParts = new LPMESH3D[PARTS_NUM];
	Triangulate();
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
	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));
			}
		}
	}
Ejemplo n.º 9
0
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();
}
Ejemplo n.º 10
0
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]);
		}
	}
}
Ejemplo n.º 11
0
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);
}
Ejemplo n.º 12
0
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
}
Ejemplo n.º 13
0
main()
{
   ReadVertices();
   PrintVertices();
   printf("%%Area of polygon = %g\n", 0.5 * AreaPoly2() );
   Triangulate();
   printf("showpage\n%%%%EOF\n");
}
Ejemplo n.º 14
0
void CIdentityCube::Update(float)
{
    if (m_isDirty)
    {
        Triangulate();
        m_isDirty = false;
    }
}
Ejemplo n.º 15
0
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);
}
Ejemplo n.º 16
0
    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);
      }
    }
Ejemplo n.º 17
0
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;
}
Ejemplo n.º 18
0
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;
}
Ejemplo n.º 19
0
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;
}
Ejemplo n.º 20
0
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;
}
Ejemplo n.º 21
0
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_;
}
Ejemplo n.º 22
0
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;
	}
}
Ejemplo n.º 23
0
//{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);
      }
   }
}
Ejemplo n.º 24
0
    int*    CacheGeometryHandler::getTriangleFaces()
    {
      if(Obj!=NULL)
      {
	Obj->updateGeometryHandler();
	if(boolTriangulated==false)	Triangulate();
	return Triangulator->getTriangleFaces();
      }
      else
      {
	return NULL;
      }
    }
Ejemplo n.º 25
0
    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);
}
Ejemplo n.º 27
0
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();
}
Ejemplo n.º 28
0
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;
}
Ejemplo n.º 29
0
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;
}
Ejemplo n.º 30
0
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]);
	}
}