Beispiel #1
0
// Add an edge from node1 to node2, and from node2 to node1, with
// the given cost. If the cost is < 0, throw a string exception.
void Graph::addEdge(int node1, int node2, double cost)
{
	if (cost < 0) {
		throw std::string("error: cost is < 0");
	}
	
	if (getCost(node1, node2) == -1.0) {
		// no edge exists yet, add them
		
		Edge edge1(cost, node2);
		Edge edge2(cost, node1);

		adjList[node1].edgeList.push_back(edge1);
		adjList[node2].edgeList.push_back(edge2);
	} else {
		// this edge already exists, just update its value
		
		auto iterator = std::find_if(std::begin(adjList[node1].edgeList),
					     std::end(adjList[node1].edgeList),
					     [&] (const Edge &edge) {
					             return edge.dest == node2;
					     });
					     
		iterator->dest = node2;
		
		iterator = std::find_if(std::begin(adjList[node2].edgeList),
					     std::end(adjList[node2].edgeList),
					     [&] (const Edge &edge) {
					             return edge.dest == node1;
					     });
					     
		iterator->dest = node1;
	}
}
bool SphereTriangleDetector::pointInTriangle(const btVector3 vertices[], const btVector3 &normal, btVector3 *p )
{
    const btVector3* p1 = &vertices[0];
    const btVector3* p2 = &vertices[1];
    const btVector3* p3 = &vertices[2];

    btVector3 edge1( *p2 - *p1 );
    btVector3 edge2( *p3 - *p2 );
    btVector3 edge3( *p1 - *p3 );

    btVector3 p1_to_p( *p - *p1 );
    btVector3 p2_to_p( *p - *p2 );
    btVector3 p3_to_p( *p - *p3 );

    btVector3 edge1_normal( edge1.cross(normal));
    btVector3 edge2_normal( edge2.cross(normal));
    btVector3 edge3_normal( edge3.cross(normal));

    btScalar r1, r2, r3;
    r1 = edge1_normal.dot( p1_to_p );
    r2 = edge2_normal.dot( p2_to_p );
    r3 = edge3_normal.dot( p3_to_p );
    if ( ( r1 > 0 && r2 > 0 && r3 > 0 ) ||
            ( r1 <= 0 && r2 <= 0 && r3 <= 0 ) )
        return true;
    return false;

}
Beispiel #3
0
float Ray::HitDistance(const Vector3& v0, const Vector3& v1, const Vector3& v2, Vector3* outNormal) const
{
    // Based on Fast, Minimum Storage Ray/Triangle Intersection by Möller & Trumbore
    // http://www.graphics.cornell.edu/pubs/1997/MT97.pdf
    // Calculate edge vectors
    Vector3 edge1(v1 - v0);
    Vector3 edge2(v2 - v0);
    
    // Calculate determinant & check backfacing
    Vector3 p(direction_.CrossProduct(edge2));
    float det = edge1.DotProduct(p);
    if (det >= M_EPSILON)
    {
        // Calculate u & v parameters and test
        Vector3 t(origin_ - v0);
        float u = t.DotProduct(p);
        if (u >= 0.0f && u <= det)
        {
            Vector3 q(t.CrossProduct(edge1));
            float v = direction_.DotProduct(q);
            if (v >= 0.0f && u + v <= det)
            {
                // There is an intersection, so calculate distance & optional normal
                if (outNormal)
                    *outNormal = edge1.CrossProduct(edge2);
                
                return edge2.DotProduct(q) / det;
            }
        }
    }
    
    return M_INFINITY;
}
Beispiel #4
0
void HFaceFormula::calcFaceNormal(HVertex v1, HVertex v2, HVertex v3, HNormal &n) {

	HNormal edge1(v1 - v2), 
		edge2(v2 - v3);

	n = edge1 ^ edge2; // cross product
}
Beispiel #5
0
//三角形v0,v1,v2
//判断点v是不是在三角形上只需要知道 O+ Dt = (1 - u - v)V0 + uV1 + vV2
//详细讲解参照:http://www.cnblogs.com/graphics/archive/2010/08/09/1795348.html
float ORay::HitDistance(const OVector3& v0, const OVector3& v1, const OVector3& v2, OVector3* outNormal) const
{
	// Based on Fast, Minimum Storage ORay/Triangle Intersection by M鰈ler & Trumbore
	// http://www.graphics.cornell.edu/pubs/1997/MT97.pdf
	// Calculate edge vectors
	OVector3 edge1(v1 - v0);
	OVector3 edge2(v2 - v0);

	// Calculate determinant & check backfacing
	OVector3 p( Vec3_CrossProduct( m_direction, edge2));
	float det = Vec3_Dotf( edge1, p );
	if (det >= EPSILON)
	{
		// Calculate u & v parameters and test
		OVector3 t(m_origin - v0);
		float u = Vec3_Dotf(t, p);
		if (u >= 0.0f && u <= det)
		{
			OVector3 q(Vec3_CrossProduct(t, edge1));
			float v = Vec3_Dotf( m_direction, q );
			if (v >= 0.0f && u + v <= det)
			{
				// There is an intersection, so calculate distance & optional normal
				if (outNormal)
					*outNormal = Vec3_CrossProduct(edge1, edge2);

				return Vec3_Dotf(edge2, q) / det;
			}
		}
	}

	return INFINITY;
}
Graph::Graph(ifstream& file,float prime_weight)
{
	vector<pair<float, float>> vertexs;
	int i = 0;						//id
	string name;					//city name
	float lat, lon;					//latitude & longitude
	float weight;					//weight = GDP * population
	bool prime;						//whether it is a prime city
	int flag = file.is_open();
	string line;
	int hz, nj;
	while (getline(file,line))
	{
		stringstream ss;
		ss << line;
		ss >> name >> lat >> lon >> weight;
		pair<float, float> v(lat, lon);
		vertexs.push_back(v);
		if (weight > prime_weight)
			prime = true;
		else
			prime = false;
		City c(i,name, v, weight,prime);
		city.push_back(c);

		//find hangzhou and nanjing
		if (name == "杭州市")
			hz = i;
		if (name == "南京市")
			nj = i;

		i++;
	}
	//construct distances set
	//dists[{i,j}] means distance between city with id i and city with id j
	for (unsigned i = 0; i < vertexs.size(); ++i)
	{
		for (unsigned j = 0; j < vertexs.size(); ++j)
		{
			pair<int, int> edge(i, j);
			dists[edge] = dist(vertexs[i], vertexs[j]);
		}
	}
	
	express[{hz, nj}] = 1; //the amount of express from hz to nj is one car
	for (unsigned i = 0; i < vertexs.size(); ++i)
	{
		for (unsigned j = 0; j < vertexs.size(); ++j)
		{
			if (i == j) continue;
			pair<int, int> edge1(i, j);
			pair<int, int> edge2(j, i);
			express[edge1] = city[i].weight * city[j].weight / (city[hz].weight * city[nj].weight);
			express[edge2] = city[i].weight * city[j].weight / (city[hz].weight * city[nj].weight);
		}
	}
}
Beispiel #7
0
bool PolygonLine :: intersects(Element *element)
{
    printf("Warning: entering PolygonLine :: intersects(Element *element).\n");

#ifdef __BOOST_MODULE
    if ( !boundingBoxIntersects(element) ) {
        return false;
    }

    double distTol = 1.0e-9;

    int numSeg = this->giveNrVertices() - 1;


    // Loop over the crack segments and test each segment for
    // overlap with the element
    for ( int segId = 1; segId <= numSeg; segId++ ) {
        if ( element->giveGeometryType() == EGT_triangle_1 ) {
            // Crack segment
            bPoint2 crackP1( this->giveVertex ( segId )->at(1), this->giveVertex ( segId )->at(2) );
            bPoint2 crackP2( this->giveVertex ( segId + 1 )->at(1), this->giveVertex ( segId + 1 )->at(2) );
            bSeg2 crackSeg(crackP1, crackP2);


            // Triangle vertices
            bPoint2 x1( element->giveNode ( 1 )->giveCoordinate(1), element->giveNode ( 1 )->giveCoordinate(2) );
            bPoint2 x2( element->giveNode ( 2 )->giveCoordinate(1), element->giveNode ( 2 )->giveCoordinate(2) );
            bPoint2 x3( element->giveNode ( 3 )->giveCoordinate(1), element->giveNode ( 3 )->giveCoordinate(2) );

            bSeg2 edge1(x1, x2);
            bSeg2 edge2(x2, x3);
            bSeg2 edge3(x3, x1);

            double d1 = bDist(crackSeg, edge1);
            if ( d1 < distTol ) {
                return true;
            }

            double d2 = bDist(crackSeg, edge2);
            if ( d2 < distTol ) {
                return true;
            }

            double d3 = bDist(crackSeg, edge3);
            if ( d3 < distTol ) {
                return true;
            }
        }
    }



#endif

    return false;
}
Beispiel #8
0
float HFaceFormula::calcTriangleFaceArea(HVertex &_v1, HVertex &_v2, HVertex &_v3)
{
	ChapillVec3<float> v1(_v1.x, _v1.y, _v1.z), 
		v2(_v2.x, _v2.y, _v2.z), 
		v3(_v3.x, _v3.y, _v3.z);

	ChapillVec3<float> edge1(v1 - v2), 
		edge2(v2 - v3);

	ChapillVec3<float> normal = edge1 ^ edge2; // cross product

	return normal.Length() / 2;
}
Beispiel #9
0
Cloth::Cloth(vec3Array& vertices, std::vector<unsigned int> &indices, const scalarType edgeKs, const scalarType edgeKd, const scalarType bendKs, const scalarType bendKd)
	: mVertices(vertices), mIndices(indices)
{
	std::map<clothEdge, clothPair> mBendPairs;
	for (int i = 0; i < indices.size(); i += 3){
		clothSpring s;
		s.kd = edgeKd; s.ks = edgeKs;
		s.type = EDGE;
		// Edge 1
		s.p1 = indices[i]; s.p2 = indices[i + 1];
		if (mBendPairs.find(clothEdge(s.p1, s.p2)) == mBendPairs.end()){
			s.restLen = glm::length(vertices[s.p1] - vertices[s.p2]);
			mSprings.push_back(s);
		}
		// Edge 2
		s.p1 = indices[i + 1]; s.p2 = indices[i + 2];
		if (mBendPairs.find(clothEdge(s.p1, s.p2)) == mBendPairs.end()){
			s.restLen = glm::length(vertices[s.p1] - vertices[s.p2]);
			mSprings.push_back(s);
		}
		// Edge 3
		s.p1 = indices[i + 2]; s.p2 = indices[i];
		if (mBendPairs.find(clothEdge(s.p1, s.p2)) == mBendPairs.end()){
			s.restLen = glm::length(vertices[s.p1] - vertices[s.p2]);
			mSprings.push_back(s);
		}
		
		clothEdge edge1(indices[i], indices[i + 1]);
		mBendPairs[edge1].add(indices[i + 2]);

		clothEdge edge2(indices[i + 1], indices[i + 2]);
		mBendPairs[edge2].add(indices[i]);

		clothEdge edge3(indices[i + 2], indices[i]);
		mBendPairs[edge1].add(indices[i + 1]);
	}

	std::map<clothEdge, clothPair>::iterator iter;
	for (iter = mBendPairs.begin(); iter != mBendPairs.end(); iter++){
		if (iter->second.isValid()){
			clothSpring s;
			s.kd = bendKd; s.ks = bendKs;
			s.type = BEND;
			s.p1 = iter->second.p1; s.p2 = iter->second.p2;
			s.restLen = glm::length(vertices[s.p1] - vertices[s.p2]);
			mSprings.push_back(s);
		}
	}
}
Beispiel #10
0
void HFaceFormula::calcTriangleFaceFormula(HVertex _v1, HVertex _v2, HVertex _v3)
{
	HNormal edge1(_v1 - _v2), 
		edge2(_v2 - _v3);

	HNormal normal = edge1 ^ edge2; // cross product

	normal.Normalize();

	a = normal.x;
	b = normal.y;
	c = normal.z;

	d = - (a * _v1.x + b * _v1.y + c * _v1.z);
}
/**
 * Break edge into several straight line
 *
 */
void Edge::breakEdge() {
	cv::Point p0; // = contours[0];
	cv::Point pend; // = contours[contours.size() - 1];
	if (listOfPoints.size() > 0) {
		p0 = listOfPoints.at(0);
		pend = listOfPoints.at(listOfPoints.size() - 1);

		if (listOfPoints.size() > 2) {
			Line line(p0, pend);
			double distance = 0;
			double maxDistance = 0; // ??????????????????
			double imax = 0;
			for (size_t i = 1; i < listOfPoints.size()-1; i++) {
				cv::Point pointi = listOfPoints.at(i);
				distance = abs(line.perpendicularDistance(pointi));
				if (distance > maxDistance) {
					maxDistance = distance;
					imax = i;
				}
			}

			if (maxDistance > 3) {
				vector<cv::Point> part1(this->listOfPoints.begin(),
						this->listOfPoints.begin() + imax + 1);
				vector<cv::Point> part2(this->listOfPoints.begin() + imax,
						this->listOfPoints.end());
				Edge edge1(part1);
				Edge edge2(part2);
				edge1.breakEdge();
				edge2.breakEdge();
			}
		}

		if (!checkPointInList(p0))
			breakPoints.push_back(p0);
		if (!checkPointInList(pend))
			breakPoints.push_back(pend);

	} else {
		return;
	}
}
Beispiel #12
0
  /*
    Convert tets and pyramids next to close (identified) points into prisms
  */
  void MakePrismsClosePoints (Mesh & mesh)
  {
    int i, j, k;
    for (i = 1; i <= mesh.GetNE(); i++)
      {
	Element & el = mesh.VolumeElement(i);
	if (el.GetType() == TET)
	  {
	    for (j = 1; j <= 3; j++)
	      for (k = j+1; k <= 4; k++)
		{
		  INDEX_2 edge(el.PNum(j), el.PNum(k));
		  edge.Sort();
		  if (mesh.GetIdentifications().GetSymmetric (el.PNum(j), el.PNum(k)))
		    {
		      int pi3 = 1, pi4 = 1;
		      while (pi3 == j || pi3 == k) pi3++;
		      pi4 = 10 - j - k - pi3;
		    
		      int p3 = el.PNum(pi3);
		      int p4 = el.PNum(pi4);
		    
		      el.SetType(PRISM);
		      el.PNum(1) = edge.I1();
		      el.PNum(2) = p3;
		      el.PNum(3) = p4;
		      el.PNum(4) = edge.I2();
		      el.PNum(5) = p3;
		      el.PNum(6) = p4;
		    }
		}
	  }

	if (el.GetType() == PYRAMID)
	  {
	    // pyramid, base face = 1,2,3,4
	  
	    for (j = 0; j <= 1; j++)
	      {
		int pi1 = el.PNum( (j+0) % 4 + 1);
		int pi2 = el.PNum( (j+1) % 4 + 1);
		int pi3 = el.PNum( (j+2) % 4 + 1);
		int pi4 = el.PNum( (j+3) % 4 + 1);
		int pi5 = el.PNum(5);

		INDEX_2 edge1(pi1, pi4);
		INDEX_2 edge2(pi2, pi3);
		edge1.Sort();
		edge2.Sort();
		if (mesh.GetIdentifications().GetSymmetric (pi1, pi4) &&
		    mesh.GetIdentifications().GetSymmetric (pi2, pi3))
		  {
		    //int p3 = el.PNum(pi3);
		    //int p4 = el.PNum(pi4);
		  
		    el.SetType(PRISM);
		    el.PNum(1) = pi1;
		    el.PNum(2) = pi2;
		    el.PNum(3) = pi5;
		    el.PNum(4) = pi4;
		    el.PNum(5) = pi3;
		    el.PNum(6) = pi5;
		  }
	      }
	  }
      }
  
    for (i = 1; i <= mesh.GetNSE(); i++)
      {
	Element2d & el = mesh.SurfaceElement(i);
	if (el.GetType() != TRIG) continue;

	for (j = 1; j <= 3; j++)
	  {
	    k = (j % 3) + 1;
	    INDEX_2 edge(el.PNum(j), el.PNum(k));
	    edge.Sort();

	    if (mesh.GetIdentifications().GetSymmetric (el.PNum(j), el.PNum(k)))
	      {
		int pi3 = 6-j-k;
		int p3 = el.PNum(pi3);
		int p1 = el.PNum(j);
		int p2 = el.PNum(k);

		el.SetType(QUAD);
		el.PNum(1) = p2;
		el.PNum(2) = p3;
		el.PNum(3) = p3;
		el.PNum(4) = p1;
	      }
	  }
      }
  }
Beispiel #13
0
void main()
{
	glfwInit();

	// Creates a window
	window = glfwCreateWindow(800, 800, "OBB - Plane Collision Detection", nullptr, nullptr);
	glfwMakeContextCurrent(window);
	glfwSwapInterval(0);

	// Initializes most things needed before the main loop
	init();

	//Generate box mesh
	struct Vertex boxVerts[24];
	boxVerts[0] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Back Left Corner
	boxVerts[1] = { -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Front Left Corner

	boxVerts[2] = { -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Front Left Corner
	boxVerts[3] = { 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Front Right Corner

	boxVerts[4] = { 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Front Right Corner
	boxVerts[5] = { 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Back Right Corner

	boxVerts[6] = { 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Back Right Corner
	boxVerts[7] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Back Left Corner


	boxVerts[8] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Back Left Corner
	boxVerts[9] = { -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Top Back Left Corner

	boxVerts[10] = { -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Front Left Corner
	boxVerts[11] = { -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Top Front Left Corner

	boxVerts[12] = { 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Front Right Corner
	boxVerts[13] = { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Top Front Right Corner

	boxVerts[14] = { 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Back Right Corner
	boxVerts[15] = { 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Top Back Right Corner


	boxVerts[16] = { -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Back Left Corner
	boxVerts[17] = { -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Front Left Corner

	boxVerts[18] = { -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Front Left Corner
	boxVerts[19] = { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Front Right Corner

	boxVerts[20] = { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Front Right Corner
	boxVerts[21] = { 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Back Right Corner

	boxVerts[22] = { 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Back Right Corner
	boxVerts[23] = { -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Back Left Corner

	box = new struct Mesh(24, boxVerts, GL_LINES);

	//Scale the box
	box->scale = box->scale * glm::scale(glm::mat4(1.0f), glm::vec3(0.1f, 0.1f, 0.1f));

	//Translate the box
	box->translation = glm::translate(box->translation, glm::vec3(-0.1f, 0.0f, 0.0f));


	//Generate the Plane mesh
	struct Vertex planeVerts[6];
	planeVerts[0] = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
	planeVerts[1] = { 0.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
	planeVerts[2] = { 0.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
	planeVerts[3] = { 0.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
	planeVerts[4] = { 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
	planeVerts[5] = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };

	plane = new struct Mesh(6, planeVerts, GL_TRIANGLES);

	//Scale the plane
	plane->scale = plane->scale * glm::scale(glm::mat4(1.0f), glm::vec3(5.0f, 5.0f, 5.0f));

	//Translate the plane
	plane->translation = glm::translate(plane->translation, glm::vec3(0.1f, 0.0f, 0.0f));

	//Set the selected shape
	selectedShape = plane;

	//Generate the colliders
	boxCollider = new struct OBB(boxVerts[3].x - boxVerts[2].x, boxVerts[9].y - boxVerts[8].y, boxVerts[1].z - boxVerts[0].z);

	//Get two edges of the plane and take the cross product for the normal (Or just hardcode it, for example we know the normal to this plane
	//Will be the Z axis, because the plane mesh lies in the XY Plane to start.
	glm::vec3 edge1(planeVerts[0].x - planeVerts[1].x, planeVerts[0].y - planeVerts[1].y, planeVerts[0].z - planeVerts[1].z);
	glm::vec3 edge2(planeVerts[1].x - planeVerts[2].x, planeVerts[1].y - planeVerts[2].y, planeVerts[1].z - planeVerts[2].z);

	glm::vec3 normal = glm::normalize(glm::cross(edge1, edge2));
	
	planeCollider = new struct Plane(normal);

	//Print controls
	std::cout << "Use WASD to move the selected shape in the XY plane.\nUse left CTRL & left shift to move the selected shape along Z axis.\n";
	std::cout << "Left click and drag the mouse to rotate the selected shape.\nUse spacebar to swap the selected shape.\n";

	// Enter the main loop.
	while (!glfwWindowShouldClose(window))
	{
		// Call to update() which will update the gameobjects.
		update();

		// Call the render function.
		renderScene();

		// Swaps the back buffer to the front buffer
		glfwSwapBuffers(window);

		// Checks to see if any events are pending and then processes them.
		glfwPollEvents();
	}

	// After the program is over, cleanup your data!
	glDeleteShader(vertex_shader);
	glDeleteShader(fragment_shader);
	glDeleteProgram(program);
	// Note: If at any point you stop using a "program" or shaders, you should free the data up then and there.

	delete box;
	delete plane;

	delete boxCollider;
	delete planeCollider;

	// Frees up GLFW memory
	glfwTerminate();
}
Beispiel #14
0
void main()
{
	glfwInit();

	// Creates a window
	window = glfwCreateWindow(800, 800, "Point - Plane Collision Detection", nullptr, nullptr);
	glfwMakeContextCurrent(window);
	glfwSwapInterval(0);

	// Initializes most things needed before the main loop
	init();



	//Generate the Plane1 mesh
	struct Vertex planeVerts[6];
	planeVerts[0] = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
	planeVerts[1] = { 0.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
	planeVerts[2] = { 0.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
	planeVerts[3] = { 0.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
	planeVerts[4] = { 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
	planeVerts[5] = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };

	plane = new struct Mesh(6, planeVerts, GL_TRIANGLES);

	//Translate the plane
	plane->translation = glm::translate(plane->translation, glm::vec3(0.15f, 0.0f, 0.0f));

	//Generate point mesh
	struct Vertex pointVert = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f };

	point = new struct Mesh(1, &pointVert, GL_POINTS);

	//Translate the plane
	point->translation = glm::translate(point->translation, glm::vec3(-0.15f, 0.0f, 0.0f));

	//Set the selected shape
	selectedShape = plane;

	//Generate plane collider

	//Get two edges of the plane and take the cross product for the normal (Or just hardcode it, for example we know the normal to this plane
	//Will be the Z axis, because the plane mesh lies in the XY Plane to start.
	glm::vec3 edge1(planeVerts[0].x - planeVerts[1].x, planeVerts[0].y - planeVerts[1].y, planeVerts[0].z - planeVerts[1].z);
	glm::vec3 edge2(planeVerts[1].x - planeVerts[2].x, planeVerts[1].y - planeVerts[2].y, planeVerts[1].z - planeVerts[2].z);

	glm::vec3 normal = glm::normalize(glm::cross(edge1, edge2));

	planeCollider = new struct Plane(normal);

	//Print controls
	std::cout << "Use WASD to move the selected shape in the XY plane.\nUse left CTRL & left shift to move the selected shape along Z axis.\n";
	std::cout << "Left click and drag the mouse to rotate the selected shape.\nUse spacebar to swap the selected shape.\n";

	// Enter the main loop.
	while (!glfwWindowShouldClose(window))
	{
		// Call to update() which will update the gameobjects.
		update();

		// Call the render function.
		renderScene();

		// Swaps the back buffer to the front buffer
		glfwSwapBuffers(window);

		// Checks to see if any events are pending and then processes them.
		glfwPollEvents();
	}

	// After the program is over, cleanup your data!
	glDeleteShader(vertex_shader);
	glDeleteShader(fragment_shader);
	glDeleteProgram(program);

	delete plane;
	delete point;

	delete planeCollider;

	// Frees up GLFW memory
	glfwTerminate();
}
Beispiel #15
0
	Subdivide (int _vertexCount, glm::vec3* _vertices, int _triangleCount, glm::ivec3* _triangles, int _subCount)
		:vertexCount(_vertexCount), triangleCount(_triangleCount * _subCount * _subCount), subCount(_subCount)
	{
		vertices.resize(vertexCount);
		triangles.resize(triangleCount);
		for (int i = 0; i < vertexCount; ++i){
			vertices[i] = _vertices[i];
		}
		std::map<SubdivideEdge, std::vector<int> > edgeMap;
		int triIndex = 0;
		for (int i = 0; i < _triangleCount; ++i){
			std::vector<int> triIndices;
			// Edge 1
			SubdivideEdge edge1(_triangles[i].x, _triangles[i].y);
			if (edgeMap.find(edge1) == edgeMap.end()){
				glm::vec3 vertexGap = (vertices[edge1.e2] - vertices[edge1.e1]) / (float)subCount;
				for (int i = 1; i < subCount; ++i){
					vertices.push_back(vertices[edge1.e1] + vertexGap * (float)i);
					edgeMap[edge1].push_back(vertexCount++);
				}
			}
			if (edge1.isExchanged){
				triIndices.push_back(edge1.e2);
				const std::vector<int>& tmpI = edgeMap[edge1];
				for (int i = 0; i < tmpI.size(); ++i){
					triIndices.push_back(tmpI[tmpI.size() - i - 1]);
				}
			}else{
				triIndices.push_back(edge1.e1);
				const std::vector<int>& tmpI = edgeMap[edge1];
				for (int i = 0; i < tmpI.size(); ++i){
					triIndices.push_back(tmpI[i]);
				}
			}
			// Edge 2
			SubdivideEdge edge2(_triangles[i].y, _triangles[i].z);
			if (edgeMap.find(edge2) == edgeMap.end()){
				glm::vec3 vertexGap = (vertices[edge2.e2] - vertices[edge2.e1]) / (float)subCount;
				for (int i = 1; i < subCount; ++i){
					vertices.push_back(vertices[edge2.e1] + vertexGap * (float)i);
					edgeMap[edge2].push_back(vertexCount++);
				}
			}
			if (edge2.isExchanged){	
				triIndices.push_back(edge2.e2);
				const std::vector<int>& tmpI = edgeMap[edge2];
				for (int i = 0; i < tmpI.size(); ++i){
					triIndices.push_back(tmpI[tmpI.size() - i - 1]);
				}			
			}else{			
				triIndices.push_back(edge2.e1);
				const std::vector<int>& tmpI = edgeMap[edge2];
				for (int i = 0; i < tmpI.size(); ++i){
					triIndices.push_back(tmpI[i]);
				}
			}
			// Edge 3
			SubdivideEdge edge3(_triangles[i].z, _triangles[i].x);
			if (edgeMap.find(edge3) == edgeMap.end()){
				glm::vec3 vertexGap = (vertices[edge3.e2] - vertices[edge3.e1]) / (float)subCount;
				for (int i = 1; i < subCount; ++i){
					vertices.push_back(vertices[edge3.e1] + vertexGap * (float)i);
					edgeMap[edge3].push_back(vertexCount++);
				}
			}
			if (edge3.isExchanged){
				triIndices.push_back(edge3.e2);
				const std::vector<int>& tmpI = edgeMap[edge3];
				for (int i = 0; i < tmpI.size(); ++i){
					triIndices.push_back(tmpI[tmpI.size() - i - 1]);
				}
			}else{
				triIndices.push_back(edge3.e1);
				const std::vector<int>& tmpI = edgeMap[edge3];
				for (int i = 0; i < tmpI.size(); ++i){
					triIndices.push_back(tmpI[i]);
				}
			}

			// Limit the subCount to [2, 5]
			subCount = subCount < 2 ? 2 : subCount;
			subCount = subCount > 5 ? 5 : subCount;

			// Create vertices inner triangle
			int currTriIndicesCnt = triIndices.size();
			for (int step = 2; step < subCount; ++step){
				glm::vec3 vertexGap = (vertices[triIndices[currTriIndicesCnt - step]] - vertices[triIndices[step]]) / (float)step;
				for (int i = 1; i < step; ++i){
					vertices.push_back(vertices[triIndices[step]] + vertexGap * (float)i);
					triIndices.push_back(vertexCount++);
				}
			}

			// Create triangle index
			int size = subCount * subCount;
			for (int i = 0; i < size; i++){
				triangles[triIndex++] = glm::ivec3(triIndices[subDivideMap[subCount][i * 3]],
												   triIndices[subDivideMap[subCount][i * 3 + 1]],
												   triIndices[subDivideMap[subCount][i * 3 + 2]]);
			}
		}
	}
void ellipseTransform(QPointF p1, QPointF p2, qreal rx, qreal ry, int largeFlag, int sweepFlag, int angel,
						qreal* startAngle, qreal *sweepLength, QRectF *rect){
	qreal r1 = (p1.x() - p2.x()) / (2.f * rx);
	qreal r2 = (p2.y() - p1.y()) / (2.f * ry);

	qreal tmp = atan(r1 / r2);
	qreal a1s[2] = { tmp, -tmp };
	
	tmp = asin(sqrt(r1*r1 + r2*r2));
	qreal a2s[2] = { tmp, -tmp };
	qreal x, y, t1, t2;

	qreal rrmin = rx*rx;
	qreal rrmax = ry*ry;
	if (rrmin > rrmax){
		tmp = rrmin;
		rrmin = rrmax;
		rrmax = tmp;
	}
	for (int i = 0; i < 2;i++)
	{
		qreal a1 = a1s[i];
		bool isBreak = false;
		for (int j = 0; j < 2; j++)
		{
			qreal a2 = a2s[j];
			t1 = a1 + a2;
			t2 = a1 - a2;
			x = p1.x() - rx*cos(t1);
			y = p1.y() - ry*sin(t1);

			qreal check1 = (p1.x() - x)*(p1.x() - x) / (rx*rx) + (p1.y() - y)*(p1.y() - y) / (ry*ry);
			qreal check2 = (p2.x() - x)*(p2.x() - x) / (rx*rx) + (p2.y() - y)*(p2.y() - y) / (ry*ry);
			
			if ( fabs(check1-1) < 1.e-6 && fabs(check2-1) < 1.e-6)
			{
				isBreak = true;
				break;
			}
		
		}
		if (isBreak)	break;
	}

	QVector3D edge1(x - p1.x(), y - p1.y(),0);
	QVector3D edge2(p2.x() - x, p2.y() - y,0);

	QVector3D cross = QVector3D::crossProduct(edge1,edge2);
	

	bool isCw = cross.z() > 0;
	if (isCw != (largeFlag == sweepFlag))
	{
		QPointF centerOfp1p2 = (p1 + p2) / 2.f;
		x = centerOfp1p2.x() * 2 - x;
		y = centerOfp1p2.y() * 2 - y;

		/*x = x0 + a * cos(t)
		y = y0 + b * sin(t)*/

		
	}


	*rect = QRect(x - rx, y - ry, rx * 2, ry * 2);

	t1 = atan2((p1.y() - y) / ry, (p1.x() - x) / rx);
	t2 = atan2((p2.y() - y) / ry, (p2.x() - x) / rx);

	*startAngle = t1 * 180 / PI;
	*startAngle = -*startAngle;
	*sweepLength = t2 * 180 / PI;
	*sweepLength = -*sweepLength;
	*sweepLength -= *startAngle;

	if ((largeFlag && fabs(*sweepLength) < 180) || (!largeFlag && fabs(*sweepLength) > 180))
	{
		if (*sweepLength < 0)
			*sweepLength = -360 - *sweepLength;
		else
			*sweepLength = 360 - *sweepLength;
	}

	if ((!sweepFlag && *sweepLength <0) || (sweepFlag && *sweepLength >0))
	{
		*sweepLength = -*sweepLength;
	}

	/*if (!isCw)
	{
		*sweepLength = fabs(*sweepLength);
	}*/
	
}
Beispiel #17
0
HE_Mesh::HE_Mesh(FVMesh& mesh)
: Mesh(nullptr)
{
    for (int vIdx = 0 ; vIdx < mesh.vertices.size() ; vIdx++)
    {
        vertices.push_back(HE_Vertex(mesh.vertices[vIdx].p, -1));
    }

    for (int fIdx = 0 ; fIdx < mesh.faces.size() ; fIdx++)
    {
        FVMeshFace& fvFace = mesh.faces[fIdx];
        HE_Face heFace;
        HE_Edge edge0(fvFace.vertex_index[0], fIdx); // vertices in face are ordered counter-clockwise
        HE_Edge edge1(fvFace.vertex_index[1], fIdx);
        HE_Edge edge2(fvFace.vertex_index[2], fIdx);

        int newEdgeIndex = edges.size();

        vertices[ fvFace.vertex_index[0] ].someEdge_idx = newEdgeIndex+0; // overwrites existing data, if present
        vertices[ fvFace.vertex_index[1] ].someEdge_idx = newEdgeIndex+1;
        vertices[ fvFace.vertex_index[2] ].someEdge_idx = newEdgeIndex+2;

        edge0.next_edge_idx = newEdgeIndex+1;
        edge1.next_edge_idx = newEdgeIndex+2;
        edge2.next_edge_idx = newEdgeIndex+0;

        edges.push_back(edge0);
        edges.push_back(edge1);
        edges.push_back(edge2);

        heFace.edge_idx[0] = newEdgeIndex+0;
        heFace.edge_idx[1] = newEdgeIndex+1;
        heFace.edge_idx[2] = newEdgeIndex+2;
        faces.push_back(heFace);

    }


    // connect half-edges:

    bool faceEdgeIsConnected[mesh.faces.size()][3] = {}; // initialize all as false


    // for each edge of each face : if it doesn't have a converse then find the converse in the edges of the opposite face
    for (int fIdx = 0 ; fIdx < mesh.faces.size() ; fIdx++)
    {
        FVMeshFace& fvFace = mesh.faces[fIdx];
        //FVMeshFaceHandle fh(mesh, fIdx);

        HE_FaceHandle fnew(*this, fIdx); // face index on FVMesh corresponds to index in HE_Mesh

//        HE_EdgeHandle edge = fnew.edge0();
//        HE_EdgeHandle edgeStart = edge;
//        do //
        for (int eIdx = 0; eIdx < 3; eIdx++)
        {
            if (faceEdgeIsConnected[fIdx][eIdx])
                { // edge.next();
                continue; }

            int edge_idx = faces[fIdx].edge_idx[eIdx];
            HE_Edge& edge = edges[ edge_idx ];
            int face2 = fvFace.connected_face_index[eIdx]; // connected_face X is connected via vertex X and vertex X+1

            if (face2 < 0)
            {
                atlas::logError("Incorrect model: disconnected faces. Support generation aborted.\n");
                exit(1); // TODO: not exit, but continue without support!
            }

            for (int e2 = 0; e2 < 3; e2++)
            {
                if (mesh.faces[face2].vertex_index[e2] == edges[edge.next_edge_idx].from_vert_idx)
                {
                    edges[ faces[face2].edge_idx[e2] ].converse_edge_idx = edge_idx;
                    edge.converse_edge_idx = faces[face2].edge_idx[e2];
                    faceEdgeIsConnected[face2][e2] = true; // the other way around doesn't have to be set; we will not pass the same edge twice
                    break;
                }
                if (e2 == 2) std::cerr << "Couldn't find converse of edge " << std::to_string(edge_idx) <<"!!!!!" << std::endl;
            }


            //edge = edge.next();
        } //while (edge != edgeStart)

    }

    HE_MESH_DEBUG_DO(
        mesh.debugOutputWholeMesh();
     )

}
Beispiel #18
0
bool Terrain::HeightMapLoad(char* filename, float sx, float sz, float maxy)
{
	//FILE *filePtr;							// Point to the current position in the file
	//BITMAPFILEHEADER bitmapFileHeader;		// Structure which stores information about file
	//BITMAPINFOHEADER bitmapInfoHeader;		// Structure which stores information about image
	int imageSize, index;
	unsigned char height;

	// Open the file
	//filePtr = fopen(filename,"rb");
	//if (filePtr == NULL)
	//	return 0;

	dx = sz;
	dz = sz;
	dy = maxy;

	

	// Get the width and height (width and length) of the image
	hminfo.terrainWidth = 145;// bitmapInfoHeader.biWidth;
	hminfo.terrainHeight = 145;// bitmapInfoHeader.biHeight;


	// Initialize the heightMap array (stores the vertices of our terrain)
	hminfo.heightMap = new IntV3[hminfo.terrainWidth * hminfo.terrainHeight];

	// We use a greyscale image, so all 3 rgb values are the same, but we only need one for the height
	// So we use this counter to skip the next two components in the image data (we read R, then skip BG)
	int k=0;

	// Read the image data into our heightMap array
	for(int j=0; j< hminfo.terrainHeight; j++)
	{
		for(int i=0; i< hminfo.terrainWidth; i++)
		{
			height = rand()%50+1;

			index = ( hminfo.terrainWidth * (hminfo.terrainHeight - 1 - j)) + i;

			hminfo.heightMap[index].x = i - (hminfo.terrainWidth - 1)/2;
			hminfo.heightMap[index].y = height;
			hminfo.heightMap[index].z = j - (hminfo.terrainHeight - 1)/2;

			k+=3;
		}
		k++;
	}


	int cols = hminfo.terrainWidth;
	int rows = hminfo.terrainHeight;

	//Create the grid
	NumVertices = 2 * rows * cols;
	NumFaces  = (rows-1)*(cols-1)*2;

	v = new struct HeightFieldVertex[NumVertices];

	for(DWORD i = 0; i < rows; ++i)
	{
		for(DWORD j = 0; j < cols; ++j)
		{
			v[i*cols+j].pos.x = hminfo.heightMap[i*cols+j].x * dx;
			v[i*cols+j].pos.y = (float(hminfo.heightMap[i*cols+j].y)/255.0) * dy;
			v[i*cols+j].pos.z = hminfo.heightMap[i*cols+j].z * dz;
			v[i*cols+j].texCoord = D3DXVECTOR2(j, i);
		}
	}

	indices = new DWORD[NumFaces * 3];

	k = 0;
	for(DWORD i = 0; i < rows-1; i++)
	{
		for(DWORD j = 0; j < cols-1; j++)
		{
			indices[k]   = i*cols+j;		// Bottom left of quad
			indices[k+1] = i*cols+j+1;		// Bottom right of quad
			indices[k+2] = (i+1)*cols+j;	// Top left of quad
			indices[k+3] = (i+1)*cols+j;	// Top left of quad
			indices[k+4] = i*cols+j+1;		// Bottom right of quad
			indices[k+5] = (i+1)*cols+j+1;	// Top right of quad

			k += 6; // next quad
		}
	}

	//normals & tangents
    std::vector<D3DXVECTOR3> tempNormal;

    //normalized and unnormalized normals
    D3DXVECTOR3 unnormalized(0.0f, 0.0f, 0.0f);

    //tangent stuff
    std::vector<D3DXVECTOR3> tempTangent;

    D3DXVECTOR3 tangent(0.0f, 0.0f, 0.0f);
    float tcU1, tcV1, tcU2, tcV2;

    //Used to get vectors (sides) from the position of the verts
    float vecX, vecY, vecZ;

    //Two edges of our triangle
    D3DXVECTOR3 edge1(0.0f, 0.0f, 0.0f);
    D3DXVECTOR3 edge2(0.0f, 0.0f, 0.0f);

    //Compute face normals
    //And Tangents
    for(int i = 0; i < NumFaces; ++i)
    {
        //Get the vector describing one edge of our triangle (edge 0,2)
        vecX = v[indices[(i*3)+1]].pos.x - v[indices[(i*3)]].pos.x;
        vecY = v[indices[(i*3)+1]].pos.y - v[indices[(i*3)]].pos.y;
        vecZ = v[indices[(i*3)+1]].pos.z - v[indices[(i*3)]].pos.z;       
        edge1 = D3DXVECTOR3(vecX, vecY, vecZ);    //Create our first edge

        //Get the vector describing another edge of our triangle (edge 2,1)
        vecX = v[indices[(i*3)+2]].pos.x - v[indices[(i*3)]].pos.x;
        vecY = v[indices[(i*3)+2]].pos.y - v[indices[(i*3)]].pos.y;
        vecZ = v[indices[(i*3)+2]].pos.z - v[indices[(i*3)]].pos.z;     
        edge2 = D3DXVECTOR3(vecX, vecY, vecZ);    //Create our second edge

        //Cross multiply the two edge vectors to get the un-normalized face normal
		D3DXVec3Cross(&unnormalized, &edge1, &edge2);
        tempNormal.push_back(unnormalized);

        //Find first texture coordinate edge 2d vector
        tcU1 = v[indices[(i*3)+1]].texCoord.x - v[indices[(i*3)]].texCoord.x;
        tcV1 = v[indices[(i*3)+1]].texCoord.y - v[indices[(i*3)]].texCoord.y;

        //Find second texture coordinate edge 2d vector
        tcU2 = v[indices[(i*3)+2]].texCoord.x - v[indices[(i*3)]].texCoord.x;
        tcV2 = v[indices[(i*3)+2]].texCoord.y - v[indices[(i*3)]].texCoord.y;

        //Find tangent using both tex coord edges and position edges
        tangent.x = (tcV2 * edge1.x - tcV1 * edge2.x)  / (tcU1 * tcV2 - tcU2 * tcV1);
        tangent.y = (tcV2 * edge1.y - tcV1 * edge2.y)  / (tcU1 * tcV2 - tcU2 * tcV1);
        tangent.z = (tcV2 * edge1.z - tcV1 * edge2.z)  / (tcU1 * tcV2 - tcU2 * tcV1);

        tempTangent.push_back(tangent);
    }

    //Compute vertex normals (normal Averaging)
    D3DXVECTOR4 normalSum(0.0f, 0.0f, 0.0f, 0.0f);
    D3DXVECTOR4 tangentSum(0.0f, 0.0f, 0.0f, 0.0f);
    int facesUsing = 0;
    float tX, tY, tZ;   //temp axis variables

    //Go through each vertex
    for(int i = 0; i < NumVertices; ++i)
    {
        //Check which triangles use this vertex
        for(int j = 0; j < NumFaces; ++j)
        {
            if(indices[j*3] == i ||
                indices[(j*3)+1] == i ||
                indices[(j*3)+2] == i)
            {
                tX = normalSum.x + tempNormal[j].x;
                tY = normalSum.y + tempNormal[j].y;
                tZ = normalSum.z + tempNormal[j].z;

                normalSum = D3DXVECTOR4(tX, tY, tZ, 0.0f);  //If a face is using the vertex, add the unormalized face normal to the normalSum
    
                facesUsing++;
            }
        }
        //Get the actual normal by dividing the normalSum by the number of faces sharing the vertex
        normalSum = normalSum / facesUsing;

		facesUsing = 0;
        //Check which triangles use this vertex
        for(int j = 0; j < NumFaces; ++j)
        {
            if(indices[j*3] == i ||
                indices[(j*3)+1] == i ||
                indices[(j*3)+2] == i)
            {
   
                //We can reuse tX, tY, tZ to sum up tangents
                tX = tangentSum.x + tempTangent[j].x;
                tY = tangentSum.y + tempTangent[j].y;
                tZ = tangentSum.z + tempTangent[j].z;

                tangentSum = D3DXVECTOR4(tX, tY, tZ, 0.0f); //sum up face tangents using this vertex

                facesUsing++;
            }
        }
        //Get the actual normal by dividing the normalSum by the number of faces sharing the vertex
        tangentSum = tangentSum / facesUsing;

        //Normalize the normalSum vector and tangent
		D3DXVec4Normalize(&normalSum, &normalSum);
		D3DXVec4Normalize(&tangentSum, &tangentSum);

        //Store the normal and tangent in our current vertex
        v[i].normal.x = normalSum.x;
        v[i].normal.y = normalSum.y;
        v[i].normal.z = normalSum.z;

        v[i].tangent.x = tangentSum.x;
        v[i].tangent.y = tangentSum.y;
        v[i].tangent.z = tangentSum.z;

		D3DXVECTOR3 bit;

		D3DXVec3Cross(&bit, &v[i].normal, &v[i].tangent);
		v[i].bitangent = -1.0 * bit;

        //Clear normalSum, tangentSum and facesUsing for next vertex
        normalSum = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f);
        tangentSum = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f);
        facesUsing = 0;
    }

	////terrain AABB
	//MinX =  -1.0 * dx * (hminfo.terrainWidth - 1)/2;
	//MinY = 0.0;
	//MinZ =  -1.0 * dz * (hminfo.terrainHeight - 1)/2;
	//MaxX =  dx * (hminfo.terrainWidth - 1)/2;
	//MaxY = dy;
	//MaxZ =  dz * (hminfo.terrainHeight - 1)/2;

 	return true;
}
Beispiel #19
0
    bool CTriangulation::Triangulate(vector<CEdgeLoop> &tri_faces, CRegion& region)
    {
		
		vector<CEdge> regionEdges;
		for(EdgeArray::iterator ol_it = region.OuterLoops.Edges.begin();ol_it != region.OuterLoops.Edges.end();ol_it++)
		{
			regionEdges.push_back(*ol_it);
		}

		for(vector<CEdgeLoop>::iterator il_it1 = region.InnerLoops.begin();il_it1 != region.InnerLoops.end();il_it1++)
		{
			CEdgeLoop currentInnerLoop = *il_it1;
			for(EdgeArray::iterator il_it2 = currentInnerLoop.Edges.begin();il_it2 != currentInnerLoop.Edges.end();il_it2++)
			{
				regionEdges.push_back(*il_it2);
			}
		}

		


		while(regionEdges.size() > 3)
		{
			vector<vec2> candidatePoints;
			for(int i = 1;i<regionEdges.size();i++)
			{
				if (CMathUtility::ToLeftExcludeOnLine(regionEdges[i].End,regionEdges[0]))
				{
					int k = 0;
					for(k = 1;k<regionEdges.size();k++)
					{
						CEdge edge1(regionEdges[0].Start,regionEdges[i].End);
						edge1.Commit();

						CEdge edge2(regionEdges[0].End,regionEdges[i].End);
						edge2.Commit();

                        //???????
						if(edge1.IsIntersectWith2(regionEdges[k]) || edge2.IsIntersectWith2(regionEdges[k]))
						{
							break;
						}
					}
					if(k == regionEdges.size())
					{
						candidatePoints.push_back(regionEdges[i].End);
					}


				}
			}

			double minR = MAXDWORD;
			vec2 LO2;

			
			for(int j = 0;j<candidatePoints.size();j++)
			{
				double r =CMathUtility::MinR(regionEdges[0].Start,regionEdges[0].End,candidatePoints[j]);
				if(r < minR)
				{
					minR = r;
					LO2 = candidatePoints[j];
				}

			}

			CEdgeLoop tmpTriangel;
			tmpTriangel.Edges.push_back(regionEdges[0]);
			CEdge tmpEdge1(regionEdges[0].End,LO2);
			tmpEdge1.Commit();
			tmpTriangel.Edges.push_back(tmpEdge1);
			CEdge tmpEdge2(LO2,regionEdges[0].Start);
			tmpEdge2.Commit();
			tmpTriangel.Edges.push_back(tmpEdge2);
			tmpTriangel.Commit();

			vector<vec2> newCandidatePoints;
            for(int m = 0;m<candidatePoints.size();m++)
			{
				if(CMathUtility::IsCanExistInCircle(candidatePoints[m],tmpTriangel))
				{
					newCandidatePoints.push_back(candidatePoints[m]);
				}

			}

			while (!newCandidatePoints.size() ==0)
			{
				minR=MAXDWORD;
				for(int m = 0;m < newCandidatePoints.size();m++)
				{
					double r=CMathUtility::MinR(regionEdges[0].Start,regionEdges[0].End,newCandidatePoints[m]);
					if(r < minR)
					{
						minR = r;
						LO2 = newCandidatePoints[m];
					}

				}
				
				tmpTriangel.Edges.clear();
				tmpTriangel.Edges.push_back(regionEdges[0]);
				tmpEdge1.Start = regionEdges[0].End;
				tmpEdge1.End = LO2;
				tmpTriangel.Edges.push_back(tmpEdge1);
				tmpEdge2.Start = LO2;
				tmpEdge2.End = regionEdges[0].Start;
				tmpTriangel.Edges.push_back(tmpEdge2);
				tmpTriangel.Commit();

				newCandidatePoints.clear();
				for (int j = 0;j<candidatePoints.size();j++)
				{
					if (CMathUtility::IsCanExistInCircle(candidatePoints[j],tmpTriangel))
					{
						newCandidatePoints.push_back(candidatePoints[j]);
					}
				}

			}

			tri_faces.push_back(tmpTriangel);

			CEdge L11_LO2(regionEdges[0].Start,LO2);
			L11_LO2.isBoundEdge = false;
			L11_LO2.Commit();
			CEdge L12_LO2(LO2,regionEdges[0].End);
			L12_LO2.isBoundEdge =false;
			L12_LO2.Commit();

			int pos_m = 0;
			int pos_n = 0;

			if(CMathUtility::IsBoundEdge(regionEdges,L11_LO2,pos_m))
			{
				L11_LO2.isBoundEdge = true;
			}
			if(CMathUtility::IsBoundEdge(regionEdges,L12_LO2,pos_n))
			{
				L12_LO2.isBoundEdge = true;
			}

			if(!L11_LO2.isBoundEdge && !L12_LO2.isBoundEdge)
			{
				CEdge tmpEdge(L12_LO2.Start,L12_LO2.End);
				tmpEdge.Commit();
				regionEdges.push_back(tmpEdge);
				regionEdges[0].End = LO2;
				regionEdges[0].Commit();
			}
			if(L11_LO2.isBoundEdge && !L12_LO2.isBoundEdge)
			{
				regionEdges[0].Start = LO2;
				regionEdges[0].Commit();
				regionEdges[pos_m] = regionEdges[regionEdges.size()-1];
				regionEdges.pop_back();
			}
			if(!L11_LO2.isBoundEdge && L12_LO2.isBoundEdge)
			{
				regionEdges[0].End = LO2;
				regionEdges[0].Commit();
				regionEdges[pos_n] = regionEdges[regionEdges.size()-1];
				regionEdges.pop_back();
			}
			if(L11_LO2.isBoundEdge && L12_LO2.isBoundEdge)
			{
				if (pos_n>pos_m)
				{
					regionEdges[pos_n] = regionEdges[regionEdges.size()-1];
					regionEdges.pop_back();

					regionEdges[pos_m] = regionEdges[regionEdges.size()-1];
					regionEdges.pop_back();
					
					regionEdges[0] = regionEdges[regionEdges.size()-1];
					regionEdges.pop_back();
				}
				else
				{
					regionEdges[pos_m] = regionEdges[regionEdges.size()-1];
					regionEdges.pop_back();

					regionEdges[pos_n] = regionEdges[regionEdges.size()-1];
					regionEdges.pop_back();

					regionEdges[0] = regionEdges[regionEdges.size()-1];
					regionEdges.pop_back();

				}

			}

		}

        // TODO
		if(regionEdges.size()==3)
		{
			CEdgeLoop tmpTriangle;
			tmpTriangle.Edges.push_back(regionEdges[0]);
			tmpTriangle.Edges.push_back(regionEdges[1]);
			tmpTriangle.Edges.push_back(regionEdges[2]);
			tmpTriangle.Commit();
			tri_faces.push_back(tmpTriangle);
		}
        return true;
    }
bool DivideAndConquerFor3DCH::RayTriangleIntersection( Ray r, TRIANGLE triangle, const vector<VERTEX*>* pVertex )
{
    VERTEX* pointOne = (*pVertex)[ triangle.p1.pointOneIndex ];
    VERTEX* pointTwo = (*pVertex)[ triangle.p2.pointTwoIndex ];
    VERTEX* pointThree = (*pVertex)[ triangle.p3.pointThreeIndex ];

    D3DXVECTOR3 edge1( pointTwo->x - pointOne->x, pointTwo->y - pointOne->y, pointTwo->z - pointOne->z );
    D3DXVECTOR3 edge2( pointThree->x - pointOne->x, pointThree->y - pointOne->y, pointThree->z - pointOne->z );

    D3DXVECTOR3 triNormal;
    D3DXVec3Cross( &triNormal, &edge1, &edge2 );
    D3DXVec3Normalize( &triNormal, &triNormal );
    double denominator = D3DXVec3Dot( &triNormal, &r.direction );

    // Ray parallels to the plane
    if( fabs( denominator ) < 0.000001 )
    {
        return false;
    }

    double d = triNormal.x * pointOne->x + triNormal.y * pointOne->y + triNormal.z * pointOne->z;
    double t = ( d - D3DXVec3Dot( &triNormal, &r.position ) ) / denominator;

    // Trianle behine the ray
    if( t <= 0 )
    {
        return false;
    }

    D3DXVECTOR3 intersectPoint = r.position + t * r.direction;

    //D3DXVECTOR3 tmp;
    //D3DXVec3Cross( &tmp, &edge1, &edge2 );
    //double totalAmount = D3DXVec3Dot( &tmp, &triNormal );
    //double totalArea = D3DXVec3Length( &tmp ) * 0.5;

    //VERTEX tmpV = pointThree - pointTwo;
    //D3DXVec3Cross( &tmp, &D3DXVECTOR3( tmpV.x, tmpV.y, tmpV.z ), &D3DXVECTOR3( intersectPoint.x - pointTwo.x, intersectPoint.y - pointTwo.y, intersectPoint.z - pointTwo.z ) );
    //double alpha = D3DXVec3Length( &tmp ) * 0.5 / totalArea;
    //
    //tmpV = pointOne - pointThree;
    //D3DXVec3Cross( &tmp, &D3DXVECTOR3( tmpV.x, tmpV.y, tmpV.z ), &D3DXVECTOR3( intersectPoint.x - pointThree.x, intersectPoint.y - pointThree.y, intersectPoint.z - pointThree.z ) );
    //double beta = D3DXVec3Length( &tmp ) * 0.5 / totalArea;

    //tmpV = pointTwo - pointOne;
    //D3DXVec3Cross( &tmp, &D3DXVECTOR3( tmpV.x, tmpV.y, tmpV.z ), &D3DXVECTOR3( intersectPoint.x - pointOne.x, intersectPoint.y - pointOne.y, intersectPoint.z - pointOne.z ) );
    //double gamma = D3DXVec3Length( &tmp ) * 0.5 / totalArea;

//	if( alpha + beta + gamma > 1.00001 )
//	{
//		return false;
//	}

    D3DXVECTOR3 tmpEdge( intersectPoint.x - pointOne->x, intersectPoint.y - pointOne->y, intersectPoint.z - pointOne->z );
    D3DXVECTOR3 tmpCrossRes;
    D3DXVec3Cross( &tmpCrossRes, &edge1, &tmpEdge );
    double alpha = D3DXVec3Dot( &triNormal, &tmpCrossRes );
    if( alpha < 0.0f )
    {
        return false;
    }

    tmpEdge = D3DXVECTOR3( intersectPoint.x - pointTwo->x, intersectPoint.y - pointTwo->y, intersectPoint.z - pointTwo->z);
    D3DXVECTOR3 tmpEdge2( pointThree->x - pointTwo->x, pointThree->y - pointTwo->y, pointThree->z - pointTwo->z );
    D3DXVec3Cross( &tmpCrossRes, &tmpEdge2, &tmpEdge );
    double beta = D3DXVec3Dot( &triNormal, &tmpCrossRes );
    if( beta < 0.0f )
    {
        return false;
    }

    tmpEdge = D3DXVECTOR3( intersectPoint.x - pointThree->x, intersectPoint.y - pointThree->y, intersectPoint.z - pointThree->z );
    tmpEdge2 = D3DXVECTOR3( pointOne->x - pointThree->x, pointOne->y - pointThree->y, pointOne->z - pointThree->z );
    D3DXVec3Cross( &tmpCrossRes, &tmpEdge2, &tmpEdge );
    double gamma = D3DXVec3Dot( &triNormal, &tmpCrossRes );
    if( gamma < 0.0f )
    {
        return false;
    }

    return true;
}
DCEL DivideAndConquerFor3DCH::BruceForceCH( vector<VERTEX*>* pVertex, const unsigned int offset )
{
    vector<TRIANGLE> triangleSet, finalTriangleSet;

    // Generate all possible triangles
    int pointSetSize = pVertex->size();
    for( int i = 0; i < pointSetSize; i++ )
    {
        for( int j = i + 1; j < pointSetSize; j++ )
        {
            for( int k = j + 1; k < pointSetSize; k++ )
            {
                // Forming face
                TRIANGLE face;
                face.p1.pointOneIndex = i;
                face.p2.pointTwoIndex = j;
                face.p3.pointThreeIndex = k;
                triangleSet.push_back( face );
            }
        }
    }

    // Find the CH for this point set by using RayAndTriangleIntersection method
    for( int i = 0; i < triangleSet.size(); i++ )
    {
        // Create a ray from this surface
        TRIANGLE triangle = triangleSet[ i ];
        // Point2 - point1
        //D3DXVECTOR3 edge1( triangle.pointTwo.x - triangle.pointOne.x, triangle.pointTwo.y - triangle.pointOne.y, triangle.pointTwo.z - triangle.pointOne.z );
        VERTEX* pointOne = (*pVertex)[ triangle.p1.pointOneIndex ];
        VERTEX* pointTwo = (*pVertex)[ triangle.p2.pointTwoIndex ];
        VERTEX* pointThree = (*pVertex)[ triangle.p3.pointThreeIndex ];

        D3DXVECTOR3 edge1( pointTwo->x - pointOne->x, pointTwo->y - pointOne->y, pointTwo->z - pointOne->z );
        D3DXVECTOR3 edge2( pointThree->x - pointOne->x, pointThree->y - pointOne->y, pointThree->z - pointOne->z );
        // point3 - point1
        //D3DXVECTOR3 edge2( triangle.pointThree.x - triangle.pointOne.x, triangle.pointThree.y - triangle.pointOne.y, triangle.pointThree.z - triangle.pointOne.z );

        D3DXVECTOR3 triangleNormal;
        D3DXVec3Cross( &triangleNormal, &edge1, &edge2 );
        D3DXVECTOR3 rayStartPoint( ( pointOne->x + pointTwo->x + pointThree->x ) / 3.0f,
                                   ( pointOne->y + pointTwo->y + pointThree->y ) / 3.0f,
                                   ( pointOne->z + pointTwo->z + pointThree->z ) / 3.0f );

        Ray ray, invRay;
        D3DXVec3Normalize( &ray.direction, &triangleNormal );
        ray.position = rayStartPoint;
        invRay = ray;
        invRay.direction *= -1.0;


        bool rayIntersect = !isNormal(ray, triangleSet[i], pVertex);
        bool invRayIntersect = !isNormal(invRay, triangleSet[i], pVertex);

        // This is the face that contribute to the convex hull and find its vertices order
        if( rayIntersect == false && invRayIntersect == true )
        {
            finalTriangleSet.push_back( triangleSet[ i ] );
        }
        else if( rayIntersect == true && invRayIntersect == false )
        {
            TRIANGLE tmpTri = triangleSet[ i ];
            int tmpVerIndex = tmpTri.p2.pointTwoIndex;
            tmpTri.p2.pointTwoIndex = tmpTri.p3.pointThreeIndex;
            tmpTri.p3.pointThreeIndex = tmpVerIndex;

            finalTriangleSet.push_back( tmpTri );
        }
    }

    DCEL dcel;
    dcel.createDCEL( &finalTriangleSet, pVertex, offset );

    return dcel;
}
void Graph::seedNodesAndEdges()
{
	/* Upon construction: seed graph with nodes and edges to connect them.
	* For now this happens manually. Ideally this happens by algorithm */

	std::shared_ptr<Node> nodeA(new Node(0, "0", 100, 50));
	std::shared_ptr<Node> nodeB(new Node(1, "1", 500, 40));
	std::shared_ptr<Node> nodeC(new Node(2, "2", 200, 300));
	std::shared_ptr<Node> nodeD(new Node(3, "3", 700, 100));
	std::shared_ptr<Node> nodeE(new Node(4, "4", 600, 400));
	std::shared_ptr<Node> nodeF(new Node(5, "5", 250, 450));
	std::shared_ptr<Node> nodeG(new Node(6, "6", 750, 500));
	std::shared_ptr<Node> nodeH(new Node(7, "7", 400, 150));
	std::shared_ptr<Node> nodeI(new Node(8, "8", 550, 250));
	std::shared_ptr<Node> nodeJ(new Node(9, "9", 100, 400));

	std::list<std::shared_ptr<Edge>> edgeList;		// Sequenced container of Edge pointers


	nodeVector.push_back(nodeA);
	std::shared_ptr<Edge> edge1(new Edge(nodeA, nodeB, calculateCost(nodeA, nodeB)));
	edgeList.push_back(edge1);
	std::shared_ptr<Edge> edge2(new Edge(nodeA, nodeC, calculateCost(nodeA, nodeC)));
	edgeList.push_back(edge2);
	edgeListVector.push_back(edgeList);
	edgeList.clear();

	nodeVector.push_back(nodeB);
	std::shared_ptr<Edge> edge3(new Edge(nodeB, nodeA, calculateCost(nodeB, nodeA)));
	edgeList.push_back(edge3);
	std::shared_ptr<Edge> edge4(new Edge(nodeB, nodeH, calculateCost(nodeB, nodeH)));
	edgeList.push_back(edge4);
	edgeListVector.push_back(edgeList);
	edgeList.clear();

	nodeVector.push_back(nodeC);
	std::shared_ptr<Edge> edge5(new Edge(nodeC, nodeA, calculateCost(nodeC, nodeA)));
	edgeList.push_back(edge5);
	std::shared_ptr<Edge> edge6(new Edge(nodeC, nodeH, calculateCost(nodeC, nodeH)));
	edgeList.push_back(edge6);
	std::shared_ptr<Edge> edge7(new Edge(nodeC, nodeE, calculateCost(nodeC, nodeE)));
	edgeList.push_back(edge7);
	std::shared_ptr<Edge> edge8(new Edge(nodeC, nodeF, calculateCost(nodeC, nodeF)));
	edgeList.push_back(edge8);
	edgeListVector.push_back(edgeList);
	edgeList.clear();

	nodeVector.push_back(nodeD);
	std::shared_ptr<Edge> edge9(new Edge(nodeD, nodeH, calculateCost(nodeD, nodeH)));
	edgeList.push_back(edge9);
	std::shared_ptr<Edge> edge10(new Edge(nodeD, nodeE, calculateCost(nodeD, nodeE)));
	edgeList.push_back(edge10);
	std::shared_ptr<Edge> edge11(new Edge(nodeD, nodeG, calculateCost(nodeD, nodeG)));
	edgeList.push_back(edge11);
	edgeListVector.push_back(edgeList);
	edgeList.clear();

	nodeVector.push_back(nodeE);
	std::shared_ptr<Edge> edge12(new Edge(nodeE, nodeC, calculateCost(nodeE, nodeC)));
	edgeList.push_back(edge12);
	std::shared_ptr<Edge> edge13(new Edge(nodeE, nodeD, calculateCost(nodeE, nodeD)));
	edgeList.push_back(edge13);
	std::shared_ptr<Edge> edge14(new Edge(nodeE, nodeG, calculateCost(nodeE, nodeG)));
	edgeList.push_back(edge14);
	std::shared_ptr<Edge> edge15(new Edge(nodeE, nodeI, calculateCost(nodeE, nodeI)));
	edgeList.push_back(edge15);
	edgeListVector.push_back(edgeList);
	edgeList.clear();

	nodeVector.push_back(nodeF);
	std::shared_ptr<Edge> edge16(new Edge(nodeF, nodeG, calculateCost(nodeF, nodeG)));
	edgeList.push_back(edge16);
	std::shared_ptr<Edge> edge17(new Edge(nodeF, nodeC, calculateCost(nodeF, nodeC)));
	edgeList.push_back(edge17);
	std::shared_ptr<Edge> edge18(new Edge(nodeF, nodeJ, calculateCost(nodeF, nodeJ)));
	edgeList.push_back(edge18);
	edgeListVector.push_back(edgeList);
	edgeList.clear();

	nodeVector.push_back(nodeG);
	std::shared_ptr<Edge> edge19(new Edge(nodeG, nodeF, calculateCost(nodeG, nodeF)));
	edgeList.push_back(edge19);
	std::shared_ptr<Edge> edge20(new Edge(nodeG, nodeD, calculateCost(nodeG, nodeD)));
	edgeList.push_back(edge20);
	std::shared_ptr<Edge> edge21(new Edge(nodeG, nodeE, calculateCost(nodeG, nodeE)));
	edgeList.push_back(edge21);
	edgeListVector.push_back(edgeList);
	edgeList.clear();

	nodeVector.push_back(nodeH);
	std::shared_ptr<Edge> edge22(new Edge(nodeH, nodeD, calculateCost(nodeH, nodeD)));
	edgeList.push_back(edge22);
	std::shared_ptr<Edge> edge23(new Edge(nodeH, nodeC, calculateCost(nodeH, nodeC)));
	edgeList.push_back(edge23);
	std::shared_ptr<Edge> edge24(new Edge(nodeH, nodeB, calculateCost(nodeH, nodeB)));
	edgeList.push_back(edge24);
	std::shared_ptr<Edge> edge25(new Edge(nodeH, nodeI, calculateCost(nodeH, nodeI)));
	edgeList.push_back(edge25);
	edgeListVector.push_back(edgeList);
	edgeList.clear();

	nodeVector.push_back(nodeI);
	std::shared_ptr<Edge> edge26(new Edge(nodeI, nodeH, calculateCost(nodeI, nodeH)));
	edgeList.push_back(edge26);
	std::shared_ptr<Edge> edge27(new Edge(nodeI, nodeE, calculateCost(nodeI, nodeE)));
	edgeList.push_back(edge27);
	edgeListVector.push_back(edgeList);
	edgeList.clear();

	nodeVector.push_back(nodeJ);
	std::shared_ptr<Edge> edge28(new Edge(nodeJ, nodeF, calculateCost(nodeJ, nodeF)));
	edgeList.push_back(edge28);
	edgeListVector.push_back(edgeList);
	edgeList.clear();
}