Crossing number/Winding number polygon test expressed as binary (Python)

837 views Asked by At

I'm trying to make an implementation of either a winding number or crossing number test, built mainly around boolean operations. The boolean requirement is due to the methods and efficiency of the underlying dataset, making it sub-optimal to delegate variables for counting other than a boolean value.

Crossing number seems easiest to implement (I would think) since it is inherently binary (even (0) vs. odd (1)), where the result of the crossing number test of each side can be xor-ed with the previous results such as in the code given below, where xyz is our evaluated coordinate. Code is adapted from http://geomalgorithms.com/a03-_inclusion.html at the end.

#Original points:
pts=[[100,100],[200,200],[300,100],[400,300],[300,400],[200,300],[100,100]]

#Extremas:
min=[pts[0][0],pts[0][1]]
max=[pts[0][0],pts[0][1]]

for i in pts:
  for j in range(2):
    if i[j]<min[j]:
      min[j]=i[j]
    if i[j]>max[j]:
      max[j]=i[j]

#New dimensions:
w=max[0]-min[0]
h=max[1]-min[1]
if len(sys.argv) > 2:
  xyz=[int(sys.argv[1]),int(sys.argv[2])]
else:
  xyz=[200,100]

#Normalize by cutting off lower than minimum, higher than maximum:
for i,p in enumerate(pts):
  pts[i]=[p[0]-min[0],p[1]-min[1]]

x=0
y=1
logic=None
counting=0
for i in range(len(pts)-1):
  test=(  ( (pts[i][y] <= xyz[y]) and (pts[i+1][y] > xyz[y]) ) or \
           ( (pts[i][y] > xyz[y]) and (pts[i+1][y] <= xyz[y]) ) ) and \
             (xyz[x] < pts[i][x] + ( (xyz[y]-pts[i][y])/(pts[i+1][y]-pts[i][y]) ) * (pts[i+1][x] - pts[i][x]))
  if logic is None:
    logic=test
  else:
    logic^=test
  if test:
    counting+=1
print logic
print counting

Results: For a whole image the binary flow results in these images where each square is one step. Obviously something is amiss, yet I can't seem to figure out why it goes all haywire after it rounds the lower right corner... Any thoughts?

Visual results

1

There are 1 answers

0
JonDeen On BEST ANSWER

Aha!

&!==and and |!==or. By changing the operators it worked.

an_image