// *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; }