Real DistRectangle3Rectangle3<Real>::GetSquared ()
{
    // Compare edges of rectangle0 to the interior of rectangle1.
    Real sqrDist = Math<Real>::MAX_REAL, sqrDistTmp;
    Segment3<Real> edge;
    int i0, i1;
    for (i1 = 0; i1 < 2; ++i1)
    {
        for (i0 = -1; i0 <= 1; i0 += 2)
        {
            edge.Center = mRectangle0->Center +
                (i0*mRectangle0->Extent[1-i1]) *
                mRectangle0->Axis[1-i1];
            edge.Direction = mRectangle0->Axis[i1];
            edge.Extent = mRectangle0->Extent[i1];
            edge.ComputeEndPoints();

            DistSegment3Rectangle3<Real> querySR(edge, *mRectangle1);
            sqrDistTmp = querySR.GetSquared();
            if (sqrDistTmp < sqrDist)
            {
                mClosestPoint0 = querySR.GetClosestPoint0();
                mClosestPoint1 = querySR.GetClosestPoint1();
                sqrDist = sqrDistTmp;
            }
        }
    }

    // Compare edges of rectangle1 to the interior of rectangle0.
    for (i1 = 0; i1 < 2; ++i1)
    {
        for (i0 = -1; i0 <= 1; i0 += 2)
        {
            edge.Center = mRectangle1->Center +
                (i0*mRectangle1->Extent[1-i1]) *
                mRectangle1->Axis[1-i1];
            edge.Direction = mRectangle1->Axis[i1];
            edge.Extent = mRectangle1->Extent[i1];
            edge.ComputeEndPoints();

            DistSegment3Rectangle3<Real> querySR(edge, *mRectangle0);
            sqrDistTmp = querySR.GetSquared();
            if (sqrDistTmp < sqrDist)
            {
                mClosestPoint0 = querySR.GetClosestPoint0();
                mClosestPoint1 = querySR.GetClosestPoint1();
                sqrDist = sqrDistTmp;
            }
        }
    }

    return sqrDist;
}
Real DistTriangle3Rectangle3<Real>::GetSquared ()
{
    // Compare edges of triangle to the interior of rectangle.
    Real sqrDist = Math<Real>::MAX_REAL, sqrDistTmp;
    Segment3<Real> edge;
    int i0, i1;
    for (i0 = 2, i1 = 0; i1 < 3; i0 = i1++)
    {
        edge.Center = ((Real)0.5)*(mTriangle->V[i0] +
            mTriangle->V[i1]);
        edge.Direction = mTriangle->V[i1] - mTriangle->V[i0];
        edge.Extent = ((Real)0.5)*edge.Direction.Normalize();
        edge.ComputeEndPoints();

        DistSegment3Rectangle3<Real> querySR(edge, *mRectangle);
        sqrDistTmp = querySR.GetSquared();
        if (sqrDistTmp < sqrDist)
        {
            // The triangle point is reported in mClosestPoint0 and the
            // rectangle point is reported in mClosestPoint1.  The querySR
            // calculator is for triangleEdge-rectangle, so GetClosestPoint0()
            // and GetClosestPoint1() must be called as listed next.
            mClosestPoint0 = querySR.GetClosestPoint0();
            mClosestPoint1 = querySR.GetClosestPoint1();
            sqrDist = sqrDistTmp;
        }
    }

    // Compare edges of rectangle to the interior of triangle.
    for (i1 = 0; i1 < 2; ++i1)
    {
        for (i0 = -1; i0 <= 1; i0 += 2)
        {
            edge.Center = mRectangle->Center +
                (i0*mRectangle->Extent[1-i1]) *
                mRectangle->Axis[1-i1];
            edge.Direction = mRectangle->Axis[i1];
            edge.Extent = mRectangle->Extent[i1];
            edge.ComputeEndPoints();

            DistSegment3Triangle3<Real> queryST(edge, *mTriangle);
            sqrDistTmp = queryST.GetSquared();
            if (sqrDistTmp < sqrDist)
            {
                // The triangle point is reported in mClosestPoint0 and the
                // rectangle point is reported in mClosestPoint1.  The queryST
                // calculator is for rectangleEdge-triangle, so
                // GetClosestPoint1() and GetClosestPoint0() must be called as
                // listed next.
                mClosestPoint0 = queryST.GetClosestPoint1();
                mClosestPoint1 = queryST.GetClosestPoint0();
                sqrDist = sqrDistTmp;
            }
        }
    }

    return sqrDist;
}