Пример #1
0
bool PointInPolyline(
    const ON_3dPoint& P,
    const ON_Polyline pline,
    double tol
    )
{
    if (!pline.IsClosed(tol)) { /* no inside to speak of */
	return false;
    }
    /* First we need to find a point that's in the plane and outside the polyline */
    ON_BoundingBox bbox;
    PolylineBBox(pline, &bbox);
    ON_3dPoint adder;
    int i;
    for (i = 0; i < pline.Count(); i++) {
	adder = P - pline[i];
	if (!VNEAR_ZERO(adder, tol)) {
	    break;
	}
    }
    ON_3dPoint DistantPoint = P;
    int multiplier = 2;
    do {
	DistantPoint += adder*multiplier;
	multiplier = multiplier*multiplier;
    } while (bbox.IsPointIn(DistantPoint, false));
    bool inside = false;
    int rv;
    ON_3dPoint result[2];
    for (i = 0; i < pline.Count() - 1; i++) {
	rv = SegmentSegmentIntersect(P, DistantPoint, pline[i], pline[i + 1], result, tol);
	if (rv == 1) {
	    inside = !inside;
	} else if (rv == 2) {
	    bu_exit(-1, "This is very unlikely bug in PointInPolyline which needs to be fixed\n");
	}
    }
    return inside;
}
Пример #2
0
int TriIntersections::Faces(
    ON_ClassArray<ON_3dPoint[3]> UNUSED(faces)
    )
{
    if (intersections.Count() == 0) {
	return 0;
    }

    /* first we get an array of all the segments we can use to make
     * our faces.
     */
    ON_SimpleArray<ON_Line> segments; /*the segments we have to make faces */
    ON_SimpleArray<bool> flippable; /* whether or not the segment has direction */
    ON_SimpleArray<bool> segexternal; /* whether or not the segment is from the edge */
    for (int i = 0; i < intersections.Count(); i++) {
	segments.Append(intersections[i]);
	segments.Append(intersections[i]);
	flippable.Append(false);
	flippable.Append(false);
	segexternal.Append(false);
	segexternal.Append(false);
    }

    for (int i = 0; i < 3; i++) {
	if (edges[i].Count() == 2) { /* the edge was never intersected */
	    segments.Append(ON_Line(edges[i][0], edges[i][0]));
	    flippable.Append(true);
	    segexternal.Append(true);
	} else {
	    for (int j = 0; j < (edges[i].Count() - 1); j++) {
		if (dir[i][j] == dir[i][j + 1]) {
		    /* this indicates an error in the intersection data */
		    return -1;
		} else if (dir[i][j] == 0 || dir[i][j+1] == 1) {
		    segments.Append(ON_Line(edges[i][j], edges[i][j+1]));
		    flippable.Append(false);
		    segexternal.Append(true);
		} else {
		    segments.Append(ON_Line(edges[i][j+1], edges[i][j]));
		    flippable.Append(false);
		    segexternal.Append(true);
		}
	    }
	}
    }

    /* Now that the segments are all set up it's time to make them
     * into faces.
     */
    ON_ClassArray<ON_Polyline> outlines;
    ON_SimpleArray<bool> line_external; /* stores whether each polyline is internal */
    ON_Polyline outline;
    while (segments.Count() != 0) {
	outline.Append(segments[0].from);
	outline.Append(segments[0].to);
	segments.Remove(0);

	int i = 0;
	bool ext = false; /* keeps track of the ternality of the path we're assembling */
	while (!outline.IsClosed(tol)) {
	    if (i >= segments.Count()) {
		return -1;
	    } else if (VNEAR_EQUAL(segments[i].from, outline[outline.Count() - 1], tol)) {
		outline.Append(segments[i].to);
	    } else if (VNEAR_EQUAL(segments[i].to, outline[0], tol)) {
		outline.Insert(0, segments[i].from);
	    } else if (VNEAR_EQUAL(segments[i].from, outline[0], tol) && flippable[i]) {
		outline.Insert(0, segments[i].to);
	    } else if (VNEAR_EQUAL(segments[i].to, outline[outline.Count() - 1], tol) && flippable[i]) {
		outline.Append(segments[i].from);
	    } else {
		i++;
		continue;
	    }

	    /* only executed when we append edge i */
	    segments.Remove(i);
	    flippable.Remove(i);
	    ext &= segexternal[i];
	    segexternal.Remove(i);
	    i = 0;
	}
	outlines.Append(outline);
	line_external.Append(ext);
    }
    /* XXX - now we need to setup the ternality tree for the paths */

    return 0;
}