예제 #1
0
unsigned int halfspace_locator(const std::array<point*, 3> &f, const point *a, const point *b) {

    Eigen::Matrix<double, 3, 3> A;

    A.col(0) << a->x - b->x,
                a->y - b->y,
                a->z - b->z;

    A.col(1) << f[1]->x - f[0]->x,
                f[1]->y - f[0]->y,
                f[1]->z - f[0]->z;

    A.col(2) << f[2]->x - f[0]->x,
                f[2]->y - f[0]->y,
                f[2]->z - f[0]->z;


    bool invertible = false;
    Eigen::Matrix<double, 3, 3> inverse;

    A.computeInverseWithCheck(inverse, invertible);    

    if (!invertible)
        return -1;

    Eigen::Matrix<double, 3, 1> B;

    B << a->x - f[0]->x,
         a->y - f[0]->y,
         a->z - f[0]->z;

    Eigen::Matrix<double, 3, 1> x = inverse * B;

    double t(x[0]), u(x[1]), v(x[2]);

    assert(t == t && u == u && v == v);

    if (std::abs(u) < 1e-10)
        u = 0;

    if (std::abs(v) < 1e-10)
        v = 0;

    double sum = u + v;

    if (std::abs(1 - sum) < 1e-10)
        sum = 1;

    unsigned int location = 0;

    /*
        half-space 21
    */

    if (sum > 1) {

        location |= 1 << 0;
        location |= 1 << 1;
    }

    else if (sum < 1) {

        location |= 1 << 0;
    }

    /*
        half-space 02
    */

    if (u > 0) {

            location |= 1 << 2;
    }

    else if (u < 0) {

        location |= 1 << 2;
        location |= 1 << 3;
    }

    /*
        half-space 10
    */

    if (v > 0) {

        location |= 1 << 4;
    }

    else if (v < 0) {

        location |= 1 << 4;
        location |= 1 << 5;
    }

    return location;
}
예제 #2
0
unsigned int fast_triangle_ray_inclusion(const std::array<point*, 3> &f, const point *a, const point *b) {

    Eigen::Matrix<double, 3, 3> A;

    A.col(0) << a->x - b->x,
                a->y - b->y,
                a->z - b->z;

    A.col(1) << f[1]->x - f[0]->x,
                f[1]->y - f[0]->y,
                f[1]->z - f[0]->z;

    A.col(2) << f[2]->x - f[0]->x,
                f[2]->y - f[0]->y,
                f[2]->z - f[0]->z;

    Eigen::Matrix<double, 3, 1> B;

    B << a->x - f[0]->x, 
         a->y - f[0]->y, 
         a->z - f[0]->z;

    Eigen::Matrix<double, 3, 3> inverse;
    bool invertible = false;
    
    A.computeInverseWithCheck(inverse, invertible);

    if (!invertible) {

        //if (verbose >= 0)
            //std::cout << "Uninvertible matrix. Skipping..." << std::endl;
        return 0;
    }

    Eigen::Matrix<double, 3, 1> x = inverse * B;

    for (int i = 0; i < 3; ++i)
        if (std::abs(x[i]) < 1e-10)
            x[i] = 0;

    double t(x[0]), u(x[1]), v(x[2]);

    if (verbose >= 3) {

        std::cout << "\nplane being examined : " << std::endl;
        for (int i = 0; i < 3; ++i)
            std::cout << *f[i] << std::endl;

        std::cout << "\ntwo points : " << std::endl;
        std::cout << *a << " <------> " << *b << std::endl;

        std::cout << "A : " << std::endl << A << std::endl;
        std::cout << "B : " << std::endl << B << std::endl;

        std::cout << "x : " << std::endl << x << std::endl;
    }

    assert(t == t && u == u && v == v); // NaN checks

    assert(t != 0);

    if (t == 1) {

        assert(u < 0 || v < 0 || u + v > 1);
        return 0; // outside triangle's interior
    }

    if (t > 0 && t < 1) {

        double sum = 0;

        for (int i = 1; i < 3; ++i) {

            if (x[i] < 0)
                return 0; // outside

            sum += x[i];
        }

        if (std::abs(sum - 1) < 1e-10)
            sum = 1;

        if (sum > 1)
            return 0; // outside

        if (u == 1) {

            return 2; // vertex 1
        }

        else if (u > 0) {

            if (v > 0) {

                if (sum == 1) {

                    return 6; // edge 21
                } else {

                    return 7; // inside
                }
            }

            else {

                return 3; // edge 10
            }
        }

        else {

            if (v == 1)
                return 4; // vertex 2

            else if (v > 0) {

                return 5; // edge 02

            }else
                return 1; // vertex 0
        }
    }

    return 0;
}