//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
Vec3d StructGridCutPlane::planeLineIntersection(const Plane& plane, const Vec3d& p1, const Vec3d& p2, const double s1, const double s2, double* s)
{
    // From http://local.wasp.uwa.edu.au/~pbourke/geometry/planeline/
    //
    // P1 (x1,y1,z1) and P2 (x2,y2,z2)
    //
    // P = P1 + u (P2 - P1)
    //
    //          A*x1 + B*y1 + C*z1 + D
    // u = ---------------------------------
    //     A*(x1-x2) + B*(y1-y2) + C*(z1-z2)

    CVF_ASSERT(s);

    const Vec3d v = p2 - p1;

    double denominator = -(plane.A()*v.x() + plane.B()*v.y() + plane.C()*v.z());
    if (denominator != 0)
    {
        double u = (plane.A()*p1.x() + plane.B()*p1.y() + plane.C()*p1.z() + plane.D())/denominator;
        if (u > 0.0 && u < 1.0)
        {
            *s = s1 + u*(s2 - s1);
            return (p1 + u*v);
        }
        else
        {
            if (u >= 1.0)
            {
                *s = s2;
                return p2;
            }
            else
            {
                *s = s1;
                return p1;
            }
        }
    }
    else
    {
        *s = s1;
        return p1;
    }
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
bool StructGridCutPlane::isCellIntersectedByPlane(const Plane& plane, const Vec3d& cellMinCoord, const Vec3d& cellMaxCoord)
{
    // See http://zach.in.tu-clausthal.de/teaching/cg_literatur/lighthouse3d_view_frustum_culling/index.html

    // Start by finding the "positive vertex" and the "negative vertex" relative to plane normal
    Vec3d pVertex(cellMinCoord);
    Vec3d nVertex(cellMaxCoord);

    if (plane.A() >= 0)
    {
        pVertex.x() = cellMaxCoord.x();
        nVertex.x() = cellMinCoord.x();
    }

    if (plane.B() >= 0)
    {
        pVertex.y() = cellMaxCoord.y();
        nVertex.y() = cellMinCoord.y();
    }

    if (plane.C() >= 0)
    {
        pVertex.z() = cellMaxCoord.z();
        nVertex.z() = cellMinCoord.z();
    }

    // Chek if both positive and negative vertex are on same side of plane
    if (plane.distanceSquared(pVertex) < 0)
    {
        if (plane.distanceSquared(nVertex) < 0)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
    else
    {
        if (plane.distanceSquared(nVertex) >= 0)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
}
Example #3
0
Frustum::Frustum(const Matrix4& m)
{
    if (m == Matrix4::Zero)
    {
        return;
    }

    Plane p;

    // Extract the LEFT plane
    p.A(m.x.w + m.x.x);
    p.B(m.y.w + m.y.x);
    p.C(m.z.w + m.z.x);
    p.D(m.t.w + m.t.x);
    p.Normalize();
    left = p;

    // Extract the RIGHT plane
    p.A(m.x.w - m.x.x);
    p.B(m.y.w - m.y.x);
    p.C(m.z.w - m.z.x);
    p.D(m.t.w - m.t.x);
    p.Normalize();
    right = p;

    // Extract the BOTTOM plane
    p.A(m.x.w + m.x.y);
    p.B(m.y.w + m.y.y);
    p.C(m.z.w + m.z.y);
    p.D(m.t.w + m.t.y);
    p.Normalize();
    bottom = p;

    // Extract the TOP plane
    p.A(m.x.w - m.x.y);
    p.B(m.y.w - m.y.y);
    p.C(m.z.w - m.z.y);
    p.D(m.t.w - m.t.y);
    p.Normalize();
    top = p;

    // Extract the NEAR plane
    p.A(m.x.w + m.x.z);
    p.B(m.y.w + m.y.z);
    p.C(m.z.w + m.z.z);
    p.D(m.t.w + m.t.z);
    p.Normalize();
    front = p;

    // Extract the FAR plane
    p.A(m.x.w - m.x.z);
    p.B(m.y.w - m.y.z);
    p.C(m.z.w - m.z.z);
    p.D(m.t.w - m.t.z);
    p.Normalize();
    back = p;
}
Example #4
0
// http://astronomy.swin.edu.au/~pbourke/geometry/planeline/
bool Line::IntersectsPlane(const Plane& plane, Vector3* intersection) const
{
    HELIUM_MATH_FUNCTION_TIMER();

    float32_t den = (plane.A() * (m_Origin.x - m_Point.x)) + (plane.B() * (m_Origin.y - m_Point.y)) + (plane.C() * (m_Origin.z - m_Point.z));

    if (fabs(den) < HELIUM_VALUE_NEAR_ZERO)
    {
        return false;
    }
    else
    {
        if (intersection)
        {
            float32_t mu = ( (plane.A() * m_Origin.x) + (plane.B() * m_Origin.y) + (plane.C() * m_Origin.z) + plane.D() ) / den;

            (*intersection) = m_Origin + (m_Point - m_Origin) * mu;
        }

        return true;
    }
}