コード例 #1
0
ファイル: Axis2Placement3D.cpp プロジェクト: cogitokat/brlcad
/*
 * Replica of STEP function:
 *   FUNCTION first_proj_axis()
 */
void
Axis2Placement3D::FirstProjAxis(double *proj,double *zaxis, double *refdir) {
    double z[3] = VINIT_ZERO;
    double v[3] = VINIT_ZERO;
    double TOL = 1e-9;

    if (zaxis == NULL)
	return;

    VMOVE(z,zaxis);
    VUNITIZE(z);
    if (refdir == NULL) {
	double xplus[3]=  {1.0,0.0,0.0};
	double xminus[3]=  {-1.0,0.0,0.0};
	if (!VNEAR_EQUAL(z, xplus, TOL) &&
	    !VNEAR_EQUAL(z, xminus, TOL))  {
	    VSET(v,1.0,0.0,0.0);
	} else {
	    VSET(v,0.0,1.0,0.0);
	}
    } else {
	double cross[3];
	double mag;

	VCROSS(cross, refdir, z);
	mag = MAGNITUDE(cross);
	if (NEAR_ZERO(mag,TOL)) {
	    return;
	} else {
	    VMOVE(v,refdir);
	    VUNITIZE(v);
	}

    }
    double x_vec[3];
    double aproj[3];
    double dot = VDOT(v,z);
    ScalarTimesVector(x_vec, dot, z);
    VectorDifference(aproj,v,x_vec);
    VSCALE(x_vec,z,dot);
    VSUB2(aproj,v, x_vec);
    VUNITIZE(aproj);
    VMOVE(proj,aproj);

    return;
}
コード例 #2
0
int PointIndex::InsertPoint(
    ON_3dPoint P
    )
{
    /* This will eventually be implemented in a much more efficient way */
    for (int i = 0; i < mesh->m_V.Count(); i++) {
	if (VNEAR_EQUAL(mesh->m_V[i], P, tol)) {
	    return i;
	}
    }
    mesh->m_V.Append(ON_3fPoint(P));
    return mesh->m_V.Count();
}
コード例 #3
0
ファイル: bn_mat.c プロジェクト: kanzure/brlcad
static int
test_bn_eigen2x2(int argc, char *argv[])
{
    fastf_t expected_val1, expected_val2, actual_val1, actual_val2;
    fastf_t a, b, c;
    vect_t expected_vec1, expected_vec2, actual_vec1, actual_vec2;

    if (argc != 9) {
	bu_exit(1, "<args> format: a b c <expected_val1> <expected_val2> <expected_vec1> <expected_vec2> [%s]\n", argv[0]);
    }

    sscanf(argv[2], "%lg", &a);
    sscanf(argv[3], "%lg", &b);
    sscanf(argv[4], "%lg", &c);
    sscanf(argv[5], "%lg", &expected_val1);
    sscanf(argv[6], "%lg", &expected_val2);
    sscanf(argv[7], "%lg,%lg,%lg", &expected_vec1[0], &expected_vec1[1], &expected_vec1[2]);
    sscanf(argv[8], "%lg,%lg,%lg", &expected_vec2[0], &expected_vec2[1], &expected_vec2[2]);

    bn_eigen2x2(&actual_val1, &actual_val2, actual_vec1, actual_vec2, a, b, c);
    return !(VNEAR_EQUAL(expected_vec1, actual_vec1, BN_TOL_DIST) && VNEAR_EQUAL(expected_vec2, actual_vec2, BN_TOL_DIST) && NEAR_EQUAL(expected_val1, actual_val1, BN_TOL_DIST) && NEAR_EQUAL(expected_val2, actual_val2, BN_TOL_DIST));
}
コード例 #4
0
ファイル: bn_mat.c プロジェクト: kanzure/brlcad
static int
test_bn_htov_move(int argc, char *argv[])
{
    hvect_t h;
    vect_t expected, actual;

    if (argc != 4) {
	bu_exit(1, "<args> format: H <expected_result> [%s]\n", argv[0]);
    }

    sscanf(argv[2], "%lg,%lg,%lg,%lg", &h[0], &h[1], &h[2], &h[3]);
    sscanf(argv[3], "%lg,%lg,%lg", &expected[0], &expected[1], &expected[2]);

    bn_htov_move(actual, h);
    return !VNEAR_EQUAL(expected, actual, BN_TOL_DIST);
}
コード例 #5
0
ファイル: bn_mat.c プロジェクト: kanzure/brlcad
static int
test_bn_vec_ae(int argc, char *argv[])
{
    vect_t expected, actual;
    fastf_t az, el;

    if (argc != 5) {
	bu_exit(1, "<args> format: az el <expected_result> [%s]\n", argv[0]);
    }

    sscanf(argv[2], "%lg", &az);
    sscanf(argv[3], "%lg", &el);
    sscanf(argv[4], "%lg,%lg,%lg", &expected[0], &expected[1], &expected[2]);

    bn_vec_ae(actual, az, el);
    return !VNEAR_EQUAL(expected, actual, BN_TOL_DIST);
}
コード例 #6
0
static void
plot_ray_img(struct application *ap,
	     const struct partition *pp,
	     double dist,
	     struct bbd_img *bi)
{
    static int plot_num;
    FILE *pfd;
    char name[256];
    point_t pt;

    sprintf(name, "bbd_%d.plot3", plot_num++);
    bu_log("plotting %s\n", name);
    if ((pfd = fopen(name, "wb")) == (FILE *)NULL) {
	bu_bomb("can't open plot3 file\n");
    }

    /* red line from ray origin to hit point */
    VJOIN1(pp->pt_inhit->hit_point, ap->a_ray.r_pt, pp->pt_inhit->hit_dist,
	   ap->a_ray.r_dir);
    if (VNEAR_EQUAL(ap->a_ray.r_pt, pp->pt_inhit->hit_point, 0.125)) {
	/* start and hit point identical, make special allowance */
	vect_t vtmp;

	pl_color(pfd, 255, 0, 128);
	VREVERSE(vtmp, ap->a_ray.r_dir);
	VJOIN1(vtmp, ap->a_ray.r_pt, 5.0, vtmp);
	pdv_3line(pfd, vtmp, pp->pt_inhit->hit_point);
    } else {
	pl_color(pfd, 255, 0, 0);
	pdv_3line(pfd, ap->a_ray.r_pt, pp->pt_inhit->hit_point);
    }

    /* yellow line from hit point to plane point */
    VJOIN1(pt, ap->a_ray.r_pt, dist, ap->a_ray.r_dir); /* point on plane */
    pl_color(pfd, 255, 255, 0);
    pdv_3line(pfd, pp->pt_inhit->hit_point, pt);

    /* green line from image origin to plane point */
    pl_color(pfd, 0, 255, 0);
    pdv_3line(pfd, pt, bi->img_origin);

    fclose(pfd);


}
コード例 #7
0
ファイル: db_diff.c プロジェクト: kanzure/brlcad
HIDDEN int
avpp_val_compare(const char *val1, const char *val2, const struct bn_tol *diff_tol)
{
    /* We need to look for numbers to do tolerance based comparisons */
    int num_compare = 1;
    int color_compare = 1;
    int pnt_compare = 1;
    double dval1, dval2;
    int c1val1, c1val2, c1val3;
    int c2val1, c2val2, c2val3;
    float p1val1, p1val2, p1val3;
    float p2val1, p2val2, p2val3;
    char *endptr;
    /* Don't try a numerical comparison unless the strings differ -
     * numerical attempts when they are not needed can introduce
     * invalid changes */
    int retval = BU_STR_EQUAL(val1, val2);

    if (!retval) {
	/* First, check for individual numbers */
	errno = 0;
	dval1 = strtod(val1, &endptr);
	if (errno == EINVAL || *endptr != '\0') num_compare--;
	errno = 0;
	dval2 = strtod(val2, &endptr);
	if (errno == EINVAL || *endptr != '\0') num_compare--;
	if (num_compare == 1) {return NEAR_EQUAL(dval1, dval2, diff_tol->dist);}

	/* If we didn't find numbers, try for colors (3 integer numbers) */
	if (sscanf(val1, "%d %d %d", &c1val1, &c1val2, &c1val3) == 3) color_compare--;
	if (sscanf(val2, "%d %d %d", &c2val1, &c2val2, &c2val3) == 3) color_compare--;
	if (color_compare == 1) return retval;

	/* If we didn't find numbers, try for points (3 floating point numbers) */
	if (sscanf(val1, "%f %f %f", &p1val1, &p1val2, &p1val3) == 3) pnt_compare--;
	if (sscanf(val2, "%f %f %f", &p2val1, &p2val2, &p2val3) == 3) pnt_compare--;

	if (pnt_compare == 1) {
	    vect_t v1, v2;
	    VSET(v1, p1val1, p1val2, p1val3);
	    VSET(v2, p2val1, p2val2, p2val3);
	    return VNEAR_EQUAL(v1, v2, diff_tol->dist);
	}
    }
    return retval;
}
コード例 #8
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;
}
コード例 #9
0
/**
 * tests whether a point is inside of the triangle using vector math
 * the point has to be in the same plane as the triangle, otherwise
 * it returns false.
 */
bool PointInTriangle(
    const ON_3dPoint& a,
    const ON_3dPoint& b,
    const ON_3dPoint& c,
    const ON_3dPoint& P,
    double tol
    )
{
    /* First we check to make sure that the point is in the plane */
    double normal[3];
    VCROSS(normal, b - a, c - a);
    VUNITIZE(normal);

    if (!NEAR_ZERO(VDOT(normal, P - a), tol))
	return false;

    /* we have a point that we know is in the plane,
     * but we need to check that it's in the triangle
     * the cleanest way to check this is to check that
     * the crosses of edges and vectors from vertices to P are all parallel or 0
     * The reader could try to prove this if s/he were ambitious
     */
    double v1[3];
    VCROSS(v1, b - a, P - a);
    if (VNEAR_ZERO(v1, tol)) {
	VSETALL(v1, 0.0);
    } else
	VUNITIZE(v1);
    double v2[3];
    VCROSS(v2, c - b, P - b);
    if (VNEAR_ZERO(v2, tol)) {
	VSETALL(v2, 0.0);
    } else
	VUNITIZE(v2);
    double v3[3];
    VCROSS(v3, a - c, P - c);
    if (VNEAR_ZERO(v3, tol)) {
	VSETALL(v3, 0.0);
    } else
	VUNITIZE(v3);

    /* basically we need to check that v1 == v2 == v3, and 0 vectors get in for free
     * if 2 of them are 0 vectors, leaving the final vector with nothing to be equal too
     * then P is in the triangle (this actually means P is a vertex of our triangle)
     * I can't think of any slick way to do this, so it gets kinda ugly
     */

    if (VNEAR_ZERO(v1, tol)) {
	if (VNEAR_ZERO(v2, tol)) {
	    return true;
	} else if (VNEAR_ZERO(v3, tol)) {
	    return true;
	} else if (VNEAR_EQUAL(v2, v3, tol)) {
	    return true;
	} else
	    return false;
    } else if (VNEAR_ZERO(v2, tol)) {
	if (VNEAR_ZERO(v3, tol)) {
	    return true;
	} else if (VNEAR_EQUAL(v1, v3, tol)) {
	    return true;
	} else
	    return false;
    } else if (VNEAR_EQUAL(v1, v2, tol)) {
	if (VNEAR_ZERO(v3, tol)) {
	    return true;
	} else if (VNEAR_EQUAL(v2, v3, tol)) {
	    return true;
	} else
	    return false;
    } else
	return false;
}
コード例 #10
0
int TriangleTriangleIntersect(
    const ON_3dPoint a,
    const ON_3dPoint b,
    const ON_3dPoint c,
    const ON_3dPoint d,
    const ON_3dPoint e,
    const ON_3dPoint f,
    ON_3dPoint out[6], /* indicates the points of intersection */
    char edge[6], /* indicates which edge the intersection points lie on ab is 0 bc is 1 etc. */
    double tol
    )
{
    ON_3dPoint abc[3] = {a, b, c};
    ON_3dPoint def[3] = {d, e, f};
    ON_3dPoint result[2];
    int rv;
    ON_3dPoint p1, p2;
    int number_found = 0; /* number_found <= 2*/
    int i, j, k; /* iterators */
    /* intersect the edges of triangle abc with triangle def*/
    for (i = 0; i < 3; i++) {
	rv = SegmentTriangleIntersect(d, e, f, abc[i], abc[(i+1)%3], result, tol);
	for (j = 0; j < rv; j++) {
	    ON_3dPoint P = result[j];
	    bool dup = false;
	    for (k = 0; k < number_found; k++) {
		if (VNEAR_EQUAL(out[k], P, tol)) {
		    dup = true;
		    break;
		}
	    }
	    if (!dup) {
		out[number_found] = P;
		edge[number_found] = i;
		number_found++;
	    }
	}
    }

    /* intersect the edges of triangle def with triangle abc*/
    for (i = 0; i < 3; i++) {
	rv = SegmentTriangleIntersect(a, b, c, def[i], def[(i + 1) % 3], result, tol);
	for (j = 0; j < rv; j++) {
	    ON_3dPoint P = result[j];
	    bool dup = false;
	    for (k = 0; k < number_found; k++) {
		if (VNEAR_EQUAL(out[k], P, tol)) {
		    dup = true;
		    break;
		}
	    }
	    if (!dup) {
		out[number_found] = P;
		edge[number_found] = i+3;
		number_found++;
	    }
	}
    }

    /* now we check if the points need to be reordered to meet our
     * condition, and reorder them if necessary
     */
    if (number_found == 2) {

	double T1norm[3];
	VCROSS(T1norm, b - a, c - a);
	VUNITIZE(T1norm);
	double T2norm[3];
	VCROSS(T2norm, b - a, c - a);
	VUNITIZE(T2norm);
	double T2normXT1norm[3];
	VCROSS(T2normXT1norm, T1norm, T2norm);

	if (VDOT(T2normXT1norm, (out[1] - out[2])) < 0) {
	    /* the points are in the wrong order swap them */
	    ON_3dPoint tmpP = out[1];
	    out[1] = out[0];
	    out[0] = tmpP;

	    /* and swap the edges they came from */
	    char tmpC = edge[1];
	    edge[1] = edge[0];
	    edge[0] = tmpC;
	}
    }
    return number_found;
}
コード例 #11
0
/**
 * intersects a triangle ABC with a line PQ
 *
 * return values:
 * -1: error
 * 0: no intersection
 * 1: intersects in a point
 * 2: intersects in a line
 */
int SegmentTriangleIntersect(
    const ON_3dPoint& a,
    const ON_3dPoint& b,
    const ON_3dPoint& c,
    const ON_3dPoint& p,
    const ON_3dPoint& q,
    ON_3dPoint out[2],
    double tol
    )
{
    ON_3dPoint triangle[3] = {a, b, c}; /* it'll be nice to have this as an array too*/

    /* First we need to get our plane into point normal form (N \dot (P - P0) = 0)
     * Where N is a normal vector, and P0 is a point in the plane
     * P0 can be any of {a, b, c} so that's easy
     * Finding N
     */

    double normal[3];
    VCROSS(normal, b - a, c - a);
    VUNITIZE(normal);

    ON_3dPoint P0 = a; /* could be b or c*/

    /* Now we've got our plane in a manageable form (two of them actually)
     * So here's the rest of the plan:
     * Every point P on the line can be written as: P = p + u (q - p)
     * We just need to find u
     * We know that when u is correct:
     * normal dot (q + u * (q-p) = N dot P0
     *		   N dot (P0 - p)
     * so u =      --------------
     *		   N dot (q - p)
     */

    if (!NEAR_ZERO(VDOT(normal, (p-q)), tol)) {/* if this is 0 it indicates the line and plane are parallel*/
	double u = VDOT(normal, (P0 - p))/VDOT(normal, (q - p));
	if (u < 0.0 || u > 1.0)	/* this means we're on the line but not the line segment*/
	    return 0;		/* so we can return early*/
	ON_3dPoint P = p + u * (q - p);

	if (PointInTriangle(a, b, c, P, tol)) {
	    out[0] = P;
	    return 1;
	}
	return 0;

    } else {
	/* If we're here it means that the line and plane are parallel*/

	if (NEAR_ZERO(VDOT(normal, p-P0), tol)) {/* yahtzee!!*/
	    /* The line segment is in the same plane as the triangle*/
	    /* So first we check if the points are inside or outside the triangle*/
	    bool p_in = PointInTriangle(a, b, c, p, tol);
	    bool q_in = PointInTriangle(a, b , c , q , tol);
	    ON_3dPoint x[2]; /* a place to put our results*/

	    if (q_in && p_in) {
		out[0] = p;
		out[1] = q;
		return 2;
	    } else if (q_in || p_in) {
		if (q_in)
		    out[0] = q;
		else
		    out[0] = p;

		int i;
		int rv;
		for (i=0; i<3; i++) {
		    rv = SegmentSegmentIntersect(triangle[i], triangle[(i+1)%3], p, q, x, tol);
		    if (rv == 1) {
			out[1] = x[0];
			return 1;
		    } else if (rv == 2) {
			out[0] = x[0];
			out[1] = x[1];
			return 2;
		    }
		}
	    } else {
		/* neither q nor p is in the triangle*/

		int i;
		int points_found = 0;
		int rv;
		for (i = 0; i < 3; i++) {
		    rv = SegmentSegmentIntersect(triangle[i], triangle[(i+1)%3], p, q, x, tol);
		    if (rv == 1) {
			if (points_found == 0 || !VNEAR_EQUAL(out[0], x[0], tol)) { /* in rare cases we can get the same point twice*/
			    out[points_found] = x[0];
			    points_found++;
			}
		    } else if (rv == 2) {
			out[0] = x[0];
			out[1] = x[1];
			return 2;
		    }
		}
		return points_found;
	    }
	} else
	    return 0;
    }
    return -1;
}
コード例 #12
0
/**
 * finds the intersection point between segments x1, x2 and x3, x4 and
 * stores the result in x we assume that the segments are coplanar.
 *
 * return values:
 *
 * 0: no intersection
 * 1: intersection in a point
 * 2: intersection in a line
 *
 *
 *            x1*                  *x3
 *                \               /
 *                 \             /
 *                  \           /
 *                   \         /
 *                    \       /
 *                     \     /
 *                      \   /
 *                       \ /
 *                        *   <----x
 *                       / \
 *                      /   \
 *                     /     \
 *                    /       \
 *                   /         \
 *                  /           \
 *               x4*             *x2
 *
 *
 *
 * the equations for the lines are:
 *
 * P(s) = x1 + s (x2 - x1) s in [0, 1]
 * Q(t) = x3 + t (x4 - x3) t in [0, 1]
 *
 * so we need to find s and t s.t. P(s) = Q(t)
 * So some vector calculus tells us that:
 *
 *       (CXB) dot (AXB)
 * s =   ---------------
 *           |AXB|^2
 *
 *      (-CXA) dot (BXA)
 * t =  ----------------
 *           |BXA|^2
 *
 *
 * Where we define:
 *
 * A = (x2-x1)
 * B = (x4-x3)
 * C = (x3-x1)
 *
 * This equation blows up if |AXB|^2 is 0 (in which case |BXA|^2 is
 * also 0), which indicates that the lines are parallel which is kind
 * of a pain.
 */
int SegmentSegmentIntersect(
    const ON_3dPoint& x1,
    const ON_3dPoint& x2,
    const ON_3dPoint& x3,
    const ON_3dPoint& x4,
    ON_3dPoint x[2],       /* segments could in degenerate cases intersect in another segment*/
    double tol
    )
{
    ON_3dPoint A = (x2 - x1);
    ON_3dPoint B = (x4 - x3);
    ON_3dPoint C = (x3 - x1);

    double AXB[3];
    VCROSS(AXB, A, B);
    double BXA[3];
    VCROSS(BXA, B, A);
    double CXB[3];
    VCROSS(CXB, C, B);
    double negC[3];
    VSCALE(negC, C, -1.0);
    double negCXA[3];
    VCROSS(negCXA, negC, A);

    if (VNEAR_ZERO(AXB, tol)) {/* the lines are parallel **commence sad music*/
	/* this is a potential bug if someone gets cheeky and passes us x2==x1*/
	double coincident_test[3];
	VCROSS(coincident_test, x4 - x2, x4 - x1);
	if (VNEAR_ZERO(coincident_test, tol)) {
	    /* the lines are coincident, meaning the segments lie on the same
	     * line but they could:
	     *	--not intersect at all
	     *  --intersect in a point
	     *  --intersect in a segment
	     * So here's the plan we. We're going to use dot products,
	     * The aspect of dot products that's important:
	     * A dot B is positive if A and B point the same way
	     * and negative when they point in opposite directions
	     * so --> dot --> is positive, but <-- dot --> is negative
	     * so if (x3-x1) dot (x4-x1) is negative, then x1 lies on the segment (x3, x4)
	     * which means that x1 should be one of the points we return so we just go
	     * through and find which points are contained in the other segment
	     * and those are our return values
	     */
	    int points = 0;
	    if (x1 == x3 || x1 == x4) {
		x[points] = x1;
		points++;
	    }
	    if (x2 == x3 || x2 == x4) {
		x[points] = x2;
		points++;
	    }
	    if (VDOT((x3 - x1), (x4 - x1)) < 0) {
		x[points] = x1;
		points++;
	    }
	    if (VDOT((x3 - x2), (x4 - x2)) < 0) {
		x[points] = x2;
		points++;
	    }
	    if (VDOT((x1 - x3), (x2 - x3)) < 0) {
		x[points] = x3;
		points++;
	    }
	    if (VDOT((x1 - x4), (x2 - x4)) < 0) {
		x[points] = x4;
		points++;
	    }

	    assert(points <= 2);
	    return points;
	}
    } else {
	double s = VDOT(CXB, AXB)/MAGSQ(AXB);
	double t = VDOT(negCXA, BXA)/MAGSQ(BXA);
	/* now we need to perform some tests to make sure we're not
	 * outside these bounds by tiny little amounts */
	if (-tol <= s && s <= 1.0 + tol && -tol <= t && t <= 1.0 + tol) {
	    ON_3dPoint Ps = x1 + s * (x2 - x1); /* The answer according to equation P*/
	    ON_3dPoint Qt = x3 + t * (x4 - x3); /* The answer according to equation Q*/
	    assert(VNEAR_EQUAL(Ps, Qt, tol)); /* check to see if they agree, just a sanity check*/
	    x[0] = Ps;
	    return 1;
	} else {
	    /* this happens when the lines through x1, x2 and x3, x4 intersect but not the segments*/
	    return 0;
	}
    }
    return 0;
}
コード例 #13
0
ファイル: bottess.c プロジェクト: kanzure/brlcad
/* returns 0 to continue, 1 if the left face was split, 2 if the right face was
 * split */
int
split_face(struct soup_s *left, unsigned long int left_face, struct soup_s *right, unsigned long int right_face, const struct bn_tol *tol) {
    struct face_s *lf, *rf;
    vect_t isectpt[2] = {{0, 0, 0}, {0, 0, 0}};
    int coplanar, r = 0;

    lf = left->faces+left_face;
    rf = right->faces+right_face;

    splitz++;
    if (gcv_tri_tri_intersect_with_isectline(left, right, lf, rf, &coplanar, (point_t *)isectpt, tol) != 0 && !VNEAR_EQUAL(isectpt[0], isectpt[1], tol->dist)) {
	splitty++;

	if (split_face_single(left, left_face, isectpt, &right->faces[right_face], tol) > 1) r|=0x1;
	if (split_face_single(right, right_face, isectpt, &left->faces[left_face], tol) > 1) r|=0x2;
    }

    return r;
}