While googling reveals, that the term "scanline" has gotten a new meaning recently, it used to be the name for an algorithm to detect intersections of lines and other geometric shapes.
The algorithms basic idea is to move a vertical "scan line" across the vertices from left to right and to record the vertical boundaries of the shape at that very x-coordinate (where the scanline is currently positioned).
Given you only have horizontal and vertical lines, the implementation of that idea can simply jump from x-coordinate of a vertex to the next, if the vertices are sorted in ascending order on the x-coordinate.
Since multiple points can share the same x-coordinate, all we need to note is, at that very x-coordinate, which are the highest and lowest y coordinates of those vertices, respectively.
Given that 32degree Celsius summertime heat, I was too lazy to create a C++ version of it. Instead, some quick hacking in Common Lisp. But it should be easy enough to read and translate. Instead of defining some kind of point structure, I simply took complex numbers, where your C++ program uses a std::pair<int,int>
. realpart/imagpart
obtain the real or imaginary part of a complex number, which, here is simply the x and y component of the vertex.
(defparameter *shape* '(#C(3 3) #C(3 6)
#C(5 6) #C(5 9)
#C(6 9) #C(6 6)
#C(6 3) #C(6 0)
#C(8 0) #C(8 3)
#C(11 3) #C(11 6)))
(defun point-in-shape-p (shape point)
(let ((x-sorted (sort
shape
#'(lambda (p1 p2)
(< (realpart p1)
(realpart p2))))))
(if (< (realpart point)
(realpart (first x-sorted)))
nil
(loop
with x-pivot = -1000000 ;; outside
with y-high = -1000000 ;; outside
with y-low = 100000 ;; outside
for v in x-sorted
when (> (realpart v) x-pivot)
do (progn
(setf x-pivot (realpart v))
(setf y-high -1000000)
(setf y-low 1000000))
when (> (imagpart v) y-high)
do (setf y-high (imagpart v))
when (< (imagpart v) y-low)
do (setf y-low (imagpart v))
when (and (<= (realpart point) x-pivot)
(<= (imagpart point) y-high)
(>= (imagpart point) y-low))
return t))))
Here a few test runs, I did for various points and the shape from your image:
CL-USER> (point-in-shape-p *shape* #C(7 8))
NIL
CL-USER> (point-in-shape-p *shape* #C(7 4))
T
CL-USER> (point-in-shape-p *shape* #C(9 2))
NIL
CL-USER> (point-in-shape-p *shape* #C(9 3))
T
No warranties, but I think it is looking good.