// A C++ program to check if a given point lies inside a given polygon
// Refer https://w...content-available-to-author-only...s.org/check-if-two-given-line-segments-intersect/
// for explanation of functions onSegment(), orientation() and doIntersect()
#include <iostream>
using namespace std;
// Define Infinite (Using INT_MAX caused overflow problems)
#define INF 10000
struct Point
{
int x;
int y;
};
// Given three colinear points p, q, r, the function checks if
// point q lies on line segment 'pr'
bool onSegment(Point p, Point q, Point r)
{
if (q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) &&
q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y))
return true;
return false;
}
// To find orientation of ordered triplet (p, q, r).
// The function returns following values
// 0 --> p, q and r are colinear
// 1 --> Clockwise
// 2 --> Counterclockwise
int orientation(Point p, Point q, Point r)
{
int val = (q.y - p.y) * (r.x - q.x) -
(q.x - p.x) * (r.y - q.y);
if (val == 0) return 0; // colinear
return (val > 0)? 1: 2; // clock or counterclock wise
}
// The function that returns true if line segment 'p1q1'
// and 'p2q2' intersect.
bool doIntersect(Point p1, Point q1, Point p2, Point q2)
{
// Find the four orientations needed for general and
// special cases
int o1 = orientation(p1, q1, p2);
int o2 = orientation(p1, q1, q2);
int o3 = orientation(p2, q2, p1);
int o4 = orientation(p2, q2, q1);
// General case
if (o1 != o2 && o3 != o4)
return true;
// Special Cases
// p1, q1 and p2 are colinear and p2 lies on segment p1q1
if (o1 == 0 && onSegment(p1, p2, q1)) return true;
// p1, q1 and p2 are colinear and q2 lies on segment p1q1
if (o2 == 0 && onSegment(p1, q2, q1)) return true;
// p2, q2 and p1 are colinear and p1 lies on segment p2q2
if (o3 == 0 && onSegment(p2, p1, q2)) return true;
// p2, q2 and q1 are colinear and q1 lies on segment p2q2
if (o4 == 0 && onSegment(p2, q1, q2)) return true;
return false; // Doesn't fall in any of the above cases
}
// Returns true if the point p lies inside the polygon[] with n vertices
bool isInside(Point polygon[], int n, Point p)
{
// There must be at least 3 vertices in polygon[]
if (n < 3) return false;
// Create a point for line segment from p to infinite
Point extreme = {INF, p.y};
// Count intersections of the above line with sides of polygon
int count = 0, i = 0;
do
{
int next = (i+1)%n;
// Check if the line segment from 'p' to 'extreme' intersects
// with the line segment from 'polygon[i]' to 'polygon[next]'
if (doIntersect(polygon[i], polygon[next], p, extreme))
{
// If the point 'p' is colinear with line segment 'i-next',
// then check if it lies on segment. If it lies, return true,
// otherwise false
if (orientation(polygon[i], p, polygon[next]) == 0)
return onSegment(polygon[i], p, polygon[next]);
count++;
}
i = next;
} while (i != 0);
// Return true if count is odd, false otherwise
return count&1; // Same as (count%2 == 1)
}
// Driver program to test above functions
int main()
{
Point polygon1[] = {{10000, 11111111}, {20000 , 22222222}, {40009 , 44454444}, {50018 , 55575555},{50027 , 55585555},{30045 , 33383333},{20045 , 22272222},{10036 , 11151111},{18 , 20000},{9 , 10000}};
int n = sizeof(polygon1)/sizeof(polygon1[0]);
Point p = {10 , 11112};
isInside(polygon1, n, p)? cout << "Yes \n": cout << "No \n";
return 0;
}
Ly8gQSBDKysgcHJvZ3JhbSB0byBjaGVjayBpZiBhIGdpdmVuIHBvaW50IGxpZXMgaW5zaWRlIGEgZ2l2ZW4gcG9seWdvbgovLyBSZWZlciBodHRwczovL3cuLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLnMub3JnL2NoZWNrLWlmLXR3by1naXZlbi1saW5lLXNlZ21lbnRzLWludGVyc2VjdC8KLy8gZm9yIGV4cGxhbmF0aW9uIG9mIGZ1bmN0aW9ucyBvblNlZ21lbnQoKSwgb3JpZW50YXRpb24oKSBhbmQgZG9JbnRlcnNlY3QoKQojaW5jbHVkZSA8aW9zdHJlYW0+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgovLyBEZWZpbmUgSW5maW5pdGUgKFVzaW5nIElOVF9NQVggY2F1c2VkIG92ZXJmbG93IHByb2JsZW1zKQojZGVmaW5lIElORiAxMDAwMAoKc3RydWN0IFBvaW50CnsKCWludCB4OwoJaW50IHk7Cn07CgovLyBHaXZlbiB0aHJlZSBjb2xpbmVhciBwb2ludHMgcCwgcSwgciwgdGhlIGZ1bmN0aW9uIGNoZWNrcyBpZgovLyBwb2ludCBxIGxpZXMgb24gbGluZSBzZWdtZW50ICdwcicKYm9vbCBvblNlZ21lbnQoUG9pbnQgcCwgUG9pbnQgcSwgUG9pbnQgcikKewoJaWYgKHEueCA8PSBtYXgocC54LCByLngpICYmIHEueCA+PSBtaW4ocC54LCByLngpICYmCgkJCXEueSA8PSBtYXgocC55LCByLnkpICYmIHEueSA+PSBtaW4ocC55LCByLnkpKQoJCXJldHVybiB0cnVlOwoJcmV0dXJuIGZhbHNlOwp9CgovLyBUbyBmaW5kIG9yaWVudGF0aW9uIG9mIG9yZGVyZWQgdHJpcGxldCAocCwgcSwgcikuCi8vIFRoZSBmdW5jdGlvbiByZXR1cm5zIGZvbGxvd2luZyB2YWx1ZXMKLy8gMCAtLT4gcCwgcSBhbmQgciBhcmUgY29saW5lYXIKLy8gMSAtLT4gQ2xvY2t3aXNlCi8vIDIgLS0+IENvdW50ZXJjbG9ja3dpc2UKaW50IG9yaWVudGF0aW9uKFBvaW50IHAsIFBvaW50IHEsIFBvaW50IHIpCnsKCWludCB2YWwgPSAocS55IC0gcC55KSAqIChyLnggLSBxLngpIC0KCQkJKHEueCAtIHAueCkgKiAoci55IC0gcS55KTsKCglpZiAodmFsID09IDApIHJldHVybiAwOyAvLyBjb2xpbmVhcgoJcmV0dXJuICh2YWwgPiAwKT8gMTogMjsgLy8gY2xvY2sgb3IgY291bnRlcmNsb2NrIHdpc2UKfQoKLy8gVGhlIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0cnVlIGlmIGxpbmUgc2VnbWVudCAncDFxMScKLy8gYW5kICdwMnEyJyBpbnRlcnNlY3QuCmJvb2wgZG9JbnRlcnNlY3QoUG9pbnQgcDEsIFBvaW50IHExLCBQb2ludCBwMiwgUG9pbnQgcTIpCnsKCS8vIEZpbmQgdGhlIGZvdXIgb3JpZW50YXRpb25zIG5lZWRlZCBmb3IgZ2VuZXJhbCBhbmQKCS8vIHNwZWNpYWwgY2FzZXMKCWludCBvMSA9IG9yaWVudGF0aW9uKHAxLCBxMSwgcDIpOwoJaW50IG8yID0gb3JpZW50YXRpb24ocDEsIHExLCBxMik7CglpbnQgbzMgPSBvcmllbnRhdGlvbihwMiwgcTIsIHAxKTsKCWludCBvNCA9IG9yaWVudGF0aW9uKHAyLCBxMiwgcTEpOwoKCS8vIEdlbmVyYWwgY2FzZQoJaWYgKG8xICE9IG8yICYmIG8zICE9IG80KQoJCXJldHVybiB0cnVlOwoKCS8vIFNwZWNpYWwgQ2FzZXMKCS8vIHAxLCBxMSBhbmQgcDIgYXJlIGNvbGluZWFyIGFuZCBwMiBsaWVzIG9uIHNlZ21lbnQgcDFxMQoJaWYgKG8xID09IDAgJiYgb25TZWdtZW50KHAxLCBwMiwgcTEpKSByZXR1cm4gdHJ1ZTsKCgkvLyBwMSwgcTEgYW5kIHAyIGFyZSBjb2xpbmVhciBhbmQgcTIgbGllcyBvbiBzZWdtZW50IHAxcTEKCWlmIChvMiA9PSAwICYmIG9uU2VnbWVudChwMSwgcTIsIHExKSkgcmV0dXJuIHRydWU7CgoJLy8gcDIsIHEyIGFuZCBwMSBhcmUgY29saW5lYXIgYW5kIHAxIGxpZXMgb24gc2VnbWVudCBwMnEyCglpZiAobzMgPT0gMCAmJiBvblNlZ21lbnQocDIsIHAxLCBxMikpIHJldHVybiB0cnVlOwoKCS8vIHAyLCBxMiBhbmQgcTEgYXJlIGNvbGluZWFyIGFuZCBxMSBsaWVzIG9uIHNlZ21lbnQgcDJxMgoJaWYgKG80ID09IDAgJiYgb25TZWdtZW50KHAyLCBxMSwgcTIpKSByZXR1cm4gdHJ1ZTsKCglyZXR1cm4gZmFsc2U7IC8vIERvZXNuJ3QgZmFsbCBpbiBhbnkgb2YgdGhlIGFib3ZlIGNhc2VzCn0KCi8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgcG9pbnQgcCBsaWVzIGluc2lkZSB0aGUgcG9seWdvbltdIHdpdGggbiB2ZXJ0aWNlcwpib29sIGlzSW5zaWRlKFBvaW50IHBvbHlnb25bXSwgaW50IG4sIFBvaW50IHApCnsKCS8vIFRoZXJlIG11c3QgYmUgYXQgbGVhc3QgMyB2ZXJ0aWNlcyBpbiBwb2x5Z29uW10KCWlmIChuIDwgMykgcmV0dXJuIGZhbHNlOwoKCS8vIENyZWF0ZSBhIHBvaW50IGZvciBsaW5lIHNlZ21lbnQgZnJvbSBwIHRvIGluZmluaXRlCglQb2ludCBleHRyZW1lID0ge0lORiwgcC55fTsKCgkvLyBDb3VudCBpbnRlcnNlY3Rpb25zIG9mIHRoZSBhYm92ZSBsaW5lIHdpdGggc2lkZXMgb2YgcG9seWdvbgoJaW50IGNvdW50ID0gMCwgaSA9IDA7CglkbwoJewoJCWludCBuZXh0ID0gKGkrMSklbjsKCgkJLy8gQ2hlY2sgaWYgdGhlIGxpbmUgc2VnbWVudCBmcm9tICdwJyB0byAnZXh0cmVtZScgaW50ZXJzZWN0cwoJCS8vIHdpdGggdGhlIGxpbmUgc2VnbWVudCBmcm9tICdwb2x5Z29uW2ldJyB0byAncG9seWdvbltuZXh0XScKCQlpZiAoZG9JbnRlcnNlY3QocG9seWdvbltpXSwgcG9seWdvbltuZXh0XSwgcCwgZXh0cmVtZSkpCgkJewoJCQkvLyBJZiB0aGUgcG9pbnQgJ3AnIGlzIGNvbGluZWFyIHdpdGggbGluZSBzZWdtZW50ICdpLW5leHQnLAoJCQkvLyB0aGVuIGNoZWNrIGlmIGl0IGxpZXMgb24gc2VnbWVudC4gSWYgaXQgbGllcywgcmV0dXJuIHRydWUsCgkJCS8vIG90aGVyd2lzZSBmYWxzZQoJCQlpZiAob3JpZW50YXRpb24ocG9seWdvbltpXSwgcCwgcG9seWdvbltuZXh0XSkgPT0gMCkKCQkJcmV0dXJuIG9uU2VnbWVudChwb2x5Z29uW2ldLCBwLCBwb2x5Z29uW25leHRdKTsKCgkJCWNvdW50Kys7CgkJfQoJCWkgPSBuZXh0OwoJfSB3aGlsZSAoaSAhPSAwKTsKCgkvLyBSZXR1cm4gdHJ1ZSBpZiBjb3VudCBpcyBvZGQsIGZhbHNlIG90aGVyd2lzZQoJcmV0dXJuIGNvdW50JjE7IC8vIFNhbWUgYXMgKGNvdW50JTIgPT0gMSkKfQoKLy8gRHJpdmVyIHByb2dyYW0gdG8gdGVzdCBhYm92ZSBmdW5jdGlvbnMKaW50IG1haW4oKQp7CglQb2ludCBwb2x5Z29uMVtdID0ge3sxMDAwMCwgMTExMTExMTF9LCB7MjAwMDAgLCAyMjIyMjIyMn0sIHs0MDAwOSAsIDQ0NDU0NDQ0fSwgezUwMDE4ICwgIDU1NTc1NTU1fSx7NTAwMjcgLCAgNTU1ODU1NTV9LHszMDA0NSAsICAzMzM4MzMzM30sezIwMDQ1ICAsIDIyMjcyMjIyfSx7MTAwMzYgICwgMTExNTExMTF9LHsxOCAgLCAgICAyMDAwMH0sezkgLCAgIDEwMDAwfX07CglpbnQgbiA9IHNpemVvZihwb2x5Z29uMSkvc2l6ZW9mKHBvbHlnb24xWzBdKTsKCVBvaW50IHAgPSB7MTAgLCAxMTExMn07Cglpc0luc2lkZShwb2x5Z29uMSwgbiwgcCk/IGNvdXQgPDwgIlllcyBcbiI6IGNvdXQgPDwgIk5vIFxuIjsKCglyZXR1cm4gMDsKfQo=