/** * @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); } }
/* 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; }