oguzakif's picture
init repo
d4b77ac
# distutils: sources = src/region.c
# distutils: include_dirs = src/
from libc.stdlib cimport malloc, free
from libc.stdio cimport sprintf
from libc.string cimport strlen
cimport c_region
cpdef enum RegionType:
EMTPY
SPECIAL
RECTANGEL
POLYGON
MASK
cdef class RegionBounds:
cdef c_region.region_bounds* _c_region_bounds
def __cinit__(self):
self._c_region_bounds = <c_region.region_bounds*>malloc(
sizeof(c_region.region_bounds))
if not self._c_region_bounds:
self._c_region_bounds = NULL
raise MemoryError()
def __init__(self, top, bottom, left, right):
self.set(top, bottom, left, right)
def __dealloc__(self):
if self._c_region_bounds is not NULL:
free(self._c_region_bounds)
self._c_region_bounds = NULL
def __str__(self):
return "top: {:.3f} bottom: {:.3f} left: {:.3f} reight: {:.3f}".format(
self._c_region_bounds.top,
self._c_region_bounds.bottom,
self._c_region_bounds.left,
self._c_region_bounds.right)
def get(self):
return (self._c_region_bounds.top,
self._c_region_bounds.bottom,
self._c_region_bounds.left,
self._c_region_bounds.right)
def set(self, top, bottom, left, right):
self._c_region_bounds.top = top
self._c_region_bounds.bottom = bottom
self._c_region_bounds.left = left
self._c_region_bounds.right = right
cdef class Rectangle:
cdef c_region.region_rectangle* _c_region_rectangle
def __cinit__(self):
self._c_region_rectangle = <c_region.region_rectangle*>malloc(
sizeof(c_region.region_rectangle))
if not self._c_region_rectangle:
self._c_region_rectangle = NULL
raise MemoryError()
def __init__(self, x, y, width, height):
self.set(x, y, width, height)
def __dealloc__(self):
if self._c_region_rectangle is not NULL:
free(self._c_region_rectangle)
self._c_region_rectangle = NULL
def __str__(self):
return "x: {:.3f} y: {:.3f} width: {:.3f} height: {:.3f}".format(
self._c_region_rectangle.x,
self._c_region_rectangle.y,
self._c_region_rectangle.width,
self._c_region_rectangle.height)
def set(self, x, y, width, height):
self._c_region_rectangle.x = x
self._c_region_rectangle.y = y
self._c_region_rectangle.width = width
self._c_region_rectangle.height = height
def get(self):
"""
return:
(x, y, width, height)
"""
return (self._c_region_rectangle.x,
self._c_region_rectangle.y,
self._c_region_rectangle.width,
self._c_region_rectangle.height)
cdef class Polygon:
cdef c_region.region_polygon* _c_region_polygon
def __cinit__(self, points):
"""
args:
points: tuple of point
points = ((1, 1), (10, 10))
"""
num = len(points)
self._c_region_polygon = <c_region.region_polygon*>malloc(
sizeof(c_region.region_polygon))
if not self._c_region_polygon:
self._c_region_polygon = NULL
raise MemoryError()
self._c_region_polygon.count = num
self._c_region_polygon.x = <float*>malloc(sizeof(float) * num)
if not self._c_region_polygon.x:
raise MemoryError()
self._c_region_polygon.y = <float*>malloc(sizeof(float) * num)
if not self._c_region_polygon.y:
raise MemoryError()
for i in range(num):
self._c_region_polygon.x[i] = points[i][0]
self._c_region_polygon.y[i] = points[i][1]
def __dealloc__(self):
if self._c_region_polygon is not NULL:
if self._c_region_polygon.x is not NULL:
free(self._c_region_polygon.x)
self._c_region_polygon.x = NULL
if self._c_region_polygon.y is not NULL:
free(self._c_region_polygon.y)
self._c_region_polygon.y = NULL
free(self._c_region_polygon)
self._c_region_polygon = NULL
def __str__(self):
ret = ""
for i in range(self._c_region_polygon.count-1):
ret += "({:.3f} {:.3f}) ".format(self._c_region_polygon.x[i],
self._c_region_polygon.y[i])
ret += "({:.3f} {:.3f})".format(self._c_region_polygon.x[i],
self._c_region_polygon.y[i])
return ret
# cdef float c_vot_overlap(c_region.region_polygon* p1, c_region.region_polygon* p2,
# bounds=RegionBounds(-float("inf"), float("inf"),
# float("inf"), float("inf"))):
# cdef float only1 = 0
# cdef float only2 = 0
# return c_region.compute_polygon_overlap(p1,
# p2,
# &only1,
# &only2,
# bounds._c_region_bounds)
# def vot_overlap(p1, p2):
# return c_vot_overlap(p1, p2)
def vot_overlap(polygon1, polygon2, bounds=None):
""" computing overlap between two polygon
Args:
polygon1: polygon tuple of points
polygon2: polygon tuple of points
bounds: tuple of (left, top, right, bottom)
Return:
overlap: overlap between two polygons
"""
polygon1_ = Polygon(polygon1)
polygon2_ = Polygon(polygon2)
cdef float only1 = 0
cdef float only2 = 0
# cdef c_region.region_polygon* c_polygon1 = polygon1._c_region_polygon
# cdef c_region.region_polygon* c_polygon2 = polygon2._c_region_polygon
cdef c_region.region_polygon* c_polygon1 = polygon1_._c_region_polygon
cdef c_region.region_polygon* c_polygon2 = polygon2_._c_region_polygon
cdef c_region.region_bounds no_bounds
if bounds is not None and len(bounds) == 2:
no_bounds.top = 0
no_bounds.bottom = bounds[1]
no_bounds.left = 0
no_bounds.right = bounds[0]
elif bounds is not None and len(bounds) == 4:
bounds.left = bounds[0]
bounds.top = bounds[1]
bounds.right = bounds[2]
bounds.bottom = bounds[3]
else:
no_bounds.top = -float("inf")
no_bounds.bottom = float("inf")
no_bounds.left = -float("inf")
no_bounds.right = float("inf")
return c_region.compute_polygon_overlap(c_polygon1,
c_polygon2,
&only1,
&only2,
no_bounds)
def vot_overlap_traj(polygons1, polygons2, bounds):
""" computing overlap between two trajectory
Args:
polygons1: list of polygon
polygons2: list of polygon
"""
overlaps = []
num = len(polygons1)
cdef float only1 = 0
cdef float only2 = 0
cdef c_region.region_bounds no_bounds
no_bounds.top = -float("inf")
no_bounds.bottom = float("inf")
no_bounds.left = -float("inf")
no_bounds.right = float("inf")
cdef c_region.region_polygon* c_polygon1
cdef c_region.region_polygon* c_polygon2
for i in range(num):
polygon1_ = Polygon(polygons1[i])
polygon2_ = Polygon(polygons2[i])
c_polygon1 = polygon1_._c_region_polygon
c_polygon2 = polygon2_._c_region_polygon
overlap = c_region.compute_polygon_overlap(c_polygon1,
c_polygon2,
&only1,
&only2,
no_bounds)
overlaps.append(overlap)
return overlaps
def vot_float2str(template, float value):
cdef bytes ptemplate = template.encode()
cdef const char* ctemplate = ptemplate
cdef char* output = <char*>malloc(sizeof(char) * 100)
if not output:
raise MemoryError()
sprintf(output, ctemplate, value)
try:
ret = output[:strlen(output)].decode()
finally:
free(output)
return ret