rendering.py 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. import numpy as np
  2. # TODO: anti-aliased version, fill_coords_aa?
  3. def fill_coords(img, fn, color):
  4. """
  5. Fill pixels of an image with coordinates matching a filter function
  6. """
  7. for y in range(img.shape[0]):
  8. for x in range(img.shape[1]):
  9. yf = y / img.shape[0]
  10. xf = x / img.shape[1]
  11. if fn(xf, yf):
  12. img[y, x] = color
  13. return img
  14. def point_in_circle(cx, cy, r):
  15. def fn(x, y):
  16. return (x-cx)*(x-cx) + (y-cy)*(y-cy) <= r * r
  17. return fn
  18. def point_in_rect(xmin, xmax, ymin, ymax):
  19. def fn(x, y):
  20. return x >= xmin and x <= xmax and y >= ymin and y <= ymax
  21. return fn
  22. def point_in_triangle(a, b, c):
  23. a = np.array(a)
  24. b = np.array(b)
  25. c = np.array(c)
  26. def fn(x, y):
  27. v0 = c - a
  28. v1 = b - a
  29. v2 = np.array((x, y)) - a
  30. # Compute dot products
  31. dot00 = np.dot(v0, v0)
  32. dot01 = np.dot(v0, v1)
  33. dot02 = np.dot(v0, v2)
  34. dot11 = np.dot(v1, v1)
  35. dot12 = np.dot(v1, v2)
  36. # Compute barycentric coordinates
  37. inv_denom = 1 / (dot00 * dot11 - dot01 * dot01)
  38. u = (dot11 * dot02 - dot01 * dot12) * inv_denom
  39. v = (dot00 * dot12 - dot01 * dot02) * inv_denom
  40. # Check if point is in triangle
  41. return (u >= 0) and (v >= 0) and (u + v) < 1
  42. return fn