intersect.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. from collections import defaultdict
  2. from utils.objparser import Mesh
  3. from PIL import Image
  4. from PIL import ImageDraw
  5. class Mesh2D(object):
  6. def __init__(self, mesh, xlim, ylim, pixel_per_meter):
  7. self.mesh = mesh
  8. self.pixel_per_meter = pixel_per_meter
  9. x_range = xlim[1] - xlim[0]
  10. y_range = ylim[1] - ylim[0]
  11. self.width = x_range * pixel_per_meter
  12. self.height = y_range * pixel_per_meter
  13. self.dx = pixel_per_meter
  14. self.dy = pixel_per_meter
  15. self.offset_x = xlim[0] * self.dx
  16. self.offset_y = ylim[0] * self.dy
  17. self.objnames = mesh.objects.keys()
  18. def getLines(self, objname, z):
  19. triangles = self.mesh.itertriangles(objname=objname)
  20. cut_plane_normal = (0, 0, 1) # normal vector in direction of z-axis
  21. cut_plane_p0 = (0, 0, z) # stuetzvektor 1m above floor
  22. lines = []
  23. for j, (p1, p2, p3) in enumerate(triangles):
  24. #~ print 'triangle %s' % j
  25. # connect p1->p2
  26. l0 = p1 # stuetzvektor
  27. l = (p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2]) # richtungsvektor
  28. line1 = (l0, l, p1, p2)
  29. # connect p2->p3
  30. l0 = p2 # stuetzvektor
  31. l = (p3[0] - p2[0], p3[1] - p2[1], p3[2] - p2[2]) # richtungsvektor
  32. line2 = (l0, l, p2, p3)
  33. # connect p3->p1
  34. l0 = p3 # stuetzvektor
  35. l = (p1[0] - p3[0], p1[1] - p3[1], p1[2] - p3[2]) # richtungsvektor
  36. line3 = (l0, l, p3, p1)
  37. # calculate d = (p0 - l0) * n / (l * n)
  38. n = cut_plane_normal
  39. p0 = cut_plane_p0
  40. intersects = []
  41. for i, (l0, l, p1, p2) in enumerate((line1, line2, line3), 1):
  42. a = p0[0] - l0[0], p0[1] - l0[1], p0[2] - l0[2]
  43. b = a[0] * n[0] + a[1] * n[1] + a[2] * n[2] # (p0 - l0) * n
  44. c = l[0] * n[0] + l[1] * n[1] + l[2] * n[2] # l * n
  45. if c == 0:
  46. pass # parallel
  47. else:
  48. d = b / float(c)
  49. # if d > 1 the point is farther away than p2
  50. if 0 < d < 1:
  51. p = l0[0] + l[0] * d, l0[1] + l[1] * d, l0[2] + l[2] * d
  52. #~ print 'triangle %s, intersect line %s at %s' % (j, i, p)
  53. intersects.append(p)
  54. assert len(intersects) in (0, 2)
  55. if len(intersects) == 2:
  56. lines.append((intersects[0], intersects[1]))
  57. return lines
  58. def meter2pixel(self, x, y):
  59. return int(x * self.dx - self.offset_x), int(self.height - y * self.dy + self.offset_y)
  60. def pixel2meter(self, x, y):
  61. return float((x + self.offset_x) / float(self.dx)), float((self.height + self.offset_y - y) / float(self.dy))
  62. def cut(self, objname, z):
  63. img = Image.new('L', (self.width, self.height), color=255)
  64. draw = ImageDraw.Draw(img)
  65. #~ print objname
  66. #~ print 'get lines'
  67. lines = self.getLines(objname, z)
  68. #~ if len(lines) == 0:
  69. #~ return None
  70. #~ print 'draw lines'
  71. for p1, p2 in lines:
  72. _p1 = self.meter2pixel(p1[0], p1[1])
  73. _p2 = self.meter2pixel(p2[0], p2[1])
  74. draw.line([_p1, _p2], fill=128)
  75. #~ print 'floodfill'
  76. ImageDraw.floodfill(img, [0, 0], 0)
  77. pixels = img.load()
  78. #~ print 'recolor lines'
  79. for x in range(self.width):
  80. for y in range(self.height):
  81. if pixels[x, y] == 128:
  82. pixels[x, y] = 255
  83. return img
  84. if __name__ == '__main__':
  85. mesh = Mesh()
  86. #~ mesh.parseObjFile('../maps/onewall/One-Wall.obj')
  87. mesh.parseObjFile('../maps/umic/umic.obj')
  88. xlim = (-1, 60)
  89. ylim = (-1, 20)
  90. print mesh.objects.keys()
  91. prepareLayer(mesh, 'Asd', xlim, ylim, 860, 413, 0.1)