Esempio n. 1
0
/*	ClassifyPathToCell
------------------------------------------------------------------------------------------
	
	Classifies a Path in relationship to this cell. A path is represented by a 2D line
	where Point A is the start of the path and Point B is the desired position.

	If the path exits this cell on a side which is linked to another cell, that cell index
	is returned in the NextCell parameter and SideHit contains the side number of the wall 
	exited through.
	
	If the path collides with a side of the cell which has no link (a solid edge), 
	SideHit contains the side number (0-2) of the colliding wall.

	In either case PointOfIntersection will contain the point where the path intersected
	with the wall of the cell if it is provided by the caller.
	
------------------------------------------------------------------------------------------
*/
NavigationCell::PATH_RESULT NavigationCell::ClassifyPathToCell(const Line2D& MotionPath, NavigationCell** pNextCell, CELL_SIDE& Side, vector2* pPointOfIntersection)const
{
	int InteriorCount = 0;

	// Check our MotionPath against each of the three cell walls
	for (int i=0; i<3; ++i)
	{
		// Classify the MotionPath endpoints as being either ON_LINE,
		// or to its LEFT_SIDE or RIGHT_SIDE. 
		// Since our triangle vertices are in clockwise order, 
		// we know that points  to the right of each line are inside the cell.
		// Points to the left are outside. 
		// We do this test using the ClassifyPoint function of Line2D

		// If the destination endpoint of the MotionPath 
		// is Not on the right side of this wall...
		if (m_Side[i].ClassifyPoint(MotionPath.EndPointB()) != Line2D::RIGHT_SIDE)
		{
			// ..and the starting endpoint of the MotionPath 
			// is Not on the left side of this wall...
			if (m_Side[i].ClassifyPoint(MotionPath.EndPointA()) != Line2D::LEFT_SIDE)
			{
				// Check to see if we intersect the wall 
				// using the Intersection function of Line2D
				Line2D::LINE_CLASSIFICATION IntersectResult = MotionPath.Intersection(m_Side[i], pPointOfIntersection);
				
				if (IntersectResult == Line2D::SEGMENTS_INTERSECT || IntersectResult == Line2D::A_BISECTS_B)
				{
					// record the link to the next adjacent cell
					// (or NULL if no attachement exists)
					// and the enumerated ID of the side we hit.
					*pNextCell = m_Link[i];
					Side = (CELL_SIDE)i;
					return (EXITING_CELL);
				}
			}
		}
		else
		{
			// The destination endpoint of the MotionPath is on the right side.
			// Increment our InteriorCount so we'll know how many walls we were
			// to the right of.
			InteriorCount++;
		}
	}

	// An InteriorCount of 3 means the destination endpoint of the MotionPath 
	// was on the right side of all walls in the cell. 
	// That means it is located within this triangle, and this is our ending cell.
	if (InteriorCount == 3)
	{
		return (ENDING_CELL);
	}

	// We only reach here is if the MotionPath does not intersect the cell at all.
	return (NO_RELATIONSHIP);
}
Esempio n. 2
0
void ConvexPolygon2D::ClipToLine(const Line2D &line) {
  if (GetPointCount() == 0) return;
  std::vector<D3DXVECTOR2> new_points;
  D3DXVECTOR2 p0 = points_[points_.size()-1];
  bool p0_inside = line.Distance(p0) < 0;
  std::vector<D3DXVECTOR2>::const_iterator it;
  for (it = points_.begin(); it != points_.end(); ++it) {
    const D3DXVECTOR2 &p1 = *it;
    bool p1_inside = line.Distance(p1) < 0;
    if (p0_inside && p1_inside) {
      new_points.push_back(p1);
    } else if (p0_inside && !p1_inside) {
      new_points.push_back(line.Intersection(Line2D(p0, p1)));
    } else if (!p0_inside && p1_inside) {
      new_points.push_back(line.Intersection(Line2D(p0, p1)));
      new_points.push_back(p1);
    } else {
      // do nothing
    }
    p0 = p1;
    p0_inside = p1_inside;
  }
  points_.swap(new_points);
}