Example #1
0
// *this Polygon is assumed to be convex
// z component of v is assumed == 0 after transformation into *this plane
bool Polygon::contains(const Grid &g, const Vector3d &w) const
{   // pmh_2014_1125
    const int NOT_INITIALIZED = -2;
    int first_turn = NOT_INITIALIZED;
    int turn;

    // build local coordinate system in the plane of *this
    const Vector3d Zhat = normal(g);
    const Vector3d origin = POINT(0);
    const Vector3d Xhat = (POINT(1) - origin).normalize();
    const Vector3d Yhat = Zhat % Xhat;

    // build q as the representation of v in this local coordinate system
    const Vector3d p = w - origin;
    const Vector3d q(p*Xhat, p*Yhat, 0.0);
    Vector3d head3d, tail3d, head, tail;

    // loop over *this Polygon's sides
    size_t i;
    const size_t n = size();
    for (size_t j = 0; j < n; ++j)
    {   // see if q is on the same side relative to each side's vector
        i = j + 1;
        if (i == n) i = 0;
        head3d = POINT(i) - origin;
        tail3d = POINT(j) - origin;
        head = Vector3d(head3d*Xhat, head3d*Yhat, 0.0);
        tail = Vector3d(tail3d*Xhat, tail3d*Yhat, 0.0);
        turn = q.get_turn(tail, head);

        if (turn != 0)
        {   // points lying exactly on the line are not considered
            if (first_turn == NOT_INITIALIZED)
            {
                first_turn = turn;
            }
            else
            {   // if turn differs from first_turn => v is outside of *this
                if (first_turn != turn) return false;
            }
        }
    }

    // all turns were in the same direction => *this contains v
    return true;
}