/**
 * @brief Counts the number of corners of a leaf are inside of the polygon
 *
 * Counts the number of corners of a leaf that are inside of the polygon. Will always
 * return a number between (and including) 0 and 4
 *
 * @param currLeaf Pointer to the leaf to test
 * @return The number of corners of the leaf that are inside of the polygon
 */
int PolygonSearch::CountCornersInsidePolygon(leaf *currLeaf)
{
	int count = 0;
	count += PointIsInsidePolygon(currLeaf->bounds[0], currLeaf->bounds[2]) ? 1 : 0;
	count += PointIsInsidePolygon(currLeaf->bounds[1], currLeaf->bounds[2]) ? 1 : 0;
	count += PointIsInsidePolygon(currLeaf->bounds[0], currLeaf->bounds[3]) ? 1 : 0;
	count += PointIsInsidePolygon(currLeaf->bounds[1], currLeaf->bounds[3]) ? 1 : 0;
	return count;
}
/**
 * @brief Counts the number of corners of a branch that are inside of the polygon
 *
 * Counts the number of corners of a branch that are inside of the polygon. Will always
 * return a number between (and including) 0 and 4
 *
 * @param currBranch Pointer to the branch to test
 * @return The number of corners of the branch that are inside of the polygon
 */
int PolygonSearch::CountCornersInsidePolygon(branch *currBranch)
{
	int count = 0;
	count += PointIsInsidePolygon(currBranch->bounds[0], currBranch->bounds[2]) ? 1 : 0;
	count += PointIsInsidePolygon(currBranch->bounds[1], currBranch->bounds[2]) ? 1 : 0;
	count += PointIsInsidePolygon(currBranch->bounds[0], currBranch->bounds[3]) ? 1 : 0;
	count += PointIsInsidePolygon(currBranch->bounds[1], currBranch->bounds[3]) ? 1 : 0;
	return count;
}
/**
 * @brief Determines if each individual Element in the partialElements list falls within the polygon
 *
 * Determines if each individual Element in the partialElements list falls within the polygon. If
 * an Element does fall within the polygon, it is added to the fullElements list.
 *
 */
void PolygonSearch::BruteForceElements()
{
	Element *currElement = 0;
	for (std::vector<Element*>::iterator it = partialElements.begin(); it != partialElements.end(); ++it)
	{
		currElement = *it;
		if (PointIsInsidePolygon(currElement->n1->normX, currElement->n1->normY) ||
		    PointIsInsidePolygon(currElement->n2->normX, currElement->n2->normY) ||
		    PointIsInsidePolygon(currElement->n3->normX, currElement->n3->normY))
			fullElements.push_back(currElement);
	}
}
/**
 * @brief Determines if each individual Node in the partialNodes list falls within the polygon
 *
 * Determines if each individual Node in the partialNodes list falls within the polygon. If a
 * Node does fall within the polygon, it is added to the fullNodes list.
 *
 */
void PolygonSearch::BruteForceNodes()
{
	Node *currNode = 0;
	for (std::vector<Node*>::iterator it = partialNodes.begin(); it != partialNodes.end(); ++it)
	{
		currNode = *it;
		if (PointIsInsidePolygon(currNode->normX, currNode->normY))
			fullNodes.push_back(currNode);
	}
}
Beispiel #5
0
/* If the bounded line intersects the polygon in more than two places,
 * then the answer is simply NO - the line is not completly outside the
 * polygon.
 * Else, if the bounded line intersects the polygon twice, we analyze
 * its end points and middle point:
 * - If both end-points are inside/on:
 *   - Test the midpoint - it it's inside then the line goes inside the
 *     polygon, otherwise it goes outside (remember, we said it
 *     intersects the polygon exactly twice!)
 * - Otherwise, there must be a subsegment of the poly-line which is
 *   partially inside!
 * Else, if it intersects exactly once:
 * - If both end-points are inside/on then it's partially inside.
 * - If exactly one end-points is inside/on then decide by the middle
 *   point (if it's partially inside then so is the line)
 * - If both end-points are outside - CAN'T HAPPEN WITH EXACTLY ONE INTERSECTION!
 * Else, if it does not intersect:
 * - Test any point inside the bounded line (end-points, middle points,
 *   etc.). If it's inside then the bounded line is inside. Otherwise
 *   it is outside
 */
static gboolean
LineIsOutsidePolygon (P2trBoundedLine *line,
                      P2trPSLG        *polygon)
{
  P2trHashSetIter iter;
  const P2trBoundedLine *polyline = NULL;
  P2trVector2 middle;
  gint intersection_count = 0, inside_count = 0;

  p2tr_pslg_iter_init (&iter, polygon);
  while (p2tr_pslg_iter_next (&iter, &polyline))
    {
      if (p2tr_bounded_line_intersect (polyline, line))
        if (++intersection_count > 2)
          return FALSE;
    }

  inside_count += (PointIsInsidePolygon (&line->start, polygon) ? 1 : 0); 
  inside_count += (PointIsInsidePolygon (&line->end, polygon) ? 1 : 0); 
  
  /* To decrease the chance of numeric errors when working on the edge points of
   * the line, the point we will test is the middle of the input line */
  middle.x = (line->start.x + line->end.x) / 2;
  middle.y = (line->start.y + line->end.y) / 2;

  if (intersection_count == 2)
    {
      if (inside_count == 2) return PointIsInsidePolygon (&middle, polygon);
      else return TRUE;
    }
  else if (intersection_count == 1)
    {
      if (inside_count == 2) return TRUE;
      else return PointIsInsidePolygon (&middle, polygon);
    }
  else return inside_count > 0;
}