Skip to content

Instantly share code, notes, and snippets.

@jarmitage
Last active March 25, 2023 13:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jarmitage/58e278b6e3e9eca8c661270eda4033f9 to your computer and use it in GitHub Desktop.
Save jarmitage/58e278b6e3e9eca8c661270eda4033f9 to your computer and use it in GitHub Desktop.
Taichi Python function to draw a polygon (excerpt functions from a class)
'''
Original: http://www.dgp.toronto.edu/~mac/e-stuff/point_in_polygon.py
'''
@ti.func
def polygon(self, x: ti.template(), y: ti.template(), rgba: vec4):
x_min, x_max = x.min(), x.max()
y_min, y_max = y.min(), y.max()
l = len(x)
for i, j in ti.ndrange(x_max-x_min, y_max-y_min):
p = [x_min+i, y_min+j]
if self._is_inside(p,x,y,l) != 0:
self.px.rgba[p[0],p[1]] = rgba
@ti.func
def _is_inside(self,p,x,y,l):
is_inside = 0
if self._polygon_mode == 'crossing':
is_inside = self._is_inside_crossing(p,x,y,l)
elif self._polygon_mode == 'winding':
is_inside = self._is_inside_winding(p,x,y,l)
return is_inside
@ti.func
def _is_inside_crossing(self,p,x,y,l):
n = 0
v0, v1 = ti.Vector([0.0,0.0]), ti.Vector([0.0,0.0])
for i in range(l):
i1 = i + 1 if i < l - 1 else 0
v0, v1 = [x[i], y[i]], [x[i1], y[i1]]
if (v0[1] <= p[1] and v1[1] > p[1]) or \
(v0[1] > p[1] and v1[1] <= p[1]):
vt = (p[1] - v0[1]) / (v1[1] - v0[1])
if p[0] < v0[0] + vt * (v1[0] - v0[0]):
n += 1
return n % 2
@ti.func
def _is_inside_winding(self,p,x,y,l):
n = 0
v0, v1 = ti.Vector([0.0,0.0]), ti.Vector([0.0,0.0])
for i in range(l):
i1 = i + 1 if i < l - 1 else 0
v0, v1 = [x[i], y[i]], [x[i1], y[i1]]
if v0[1] <= p[1] and v1[1] > p[1] and \
(v0 - v1).cross(p - v1) > 0:
n += 1
elif v1[1] <= p[1] and (v0-v1).cross(p-v1) < 0:
n -= 1
return n
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment