Dinple / TaxiVoronoi_py3

In Taxi, aka Manhattan metric Voronoi, creates polygons for centroids

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

TaxiVoronoi generates a polygonal representation of a voronoi diagram in manhattan metric

sfTest.py requires python-sfml.

The bottleneck is in the border intersects, so I took a crack at cythonizing that part.
Run TaxiVoronoi/TaxiVoronoi/Intersect_cython/comp to compile Intersect.so.
This has greatly improved speed, with only a few variable type declarations.

So far, only tested in a (0,0),(1,1) range of points.
Might require Poly.epsilon adjustment for larger/smaller scale, if verts aren't welding between polies. Currently it's 1e-04. 

It will fail if any two supplied centroids are horizontal, vertical, or a 45 degree diagonal to each other. 
With the RandomPointGrid settings where they are (in sfTest.py), this happens frequently.

polies,verts = TaxiVoronoi(centroids)
	centroids:	list of 2d points, aka sites, also centroids
	polies: list of Poly
	verts: list of 2d verts. Adjacent polies index the same verts.

Poly:
	centroid
	neighbors:	list of Poly - one per adjacent poly
	neighborIndices: list of indices of polies returned by TaxiVoronoi
	verts: list of indices of verts returned by TaxiVoronoi
	borders: list of Border - one per neighbor
	isClosed: boolean - outer polies wont be
		isClosed= borders[0][0]==borders[-1][-1]
		a closed poly's 1st and last are duplicate indices

	polies are wound counter-clockwise by default. Reverse them with
		Poly.WindingOrderUsed=Poly.clockwise or poly.reverse().

Border:
	axis: (+-1,0) or (0,+-1) or None - horizontal, vertical, or as of yet unhandled scenario
	lines: [ray,segment,ray]
	seg: the afforementioned segment
	verts: much like Poly.verts

	a border's rays who an open vert of a non-closed poly lies on could be used to complete it's representation


note: This can be done faster. I'm seeing good results so far in a process surmized as:
(i hope you like python)
(P= the centroids)
determine bounds of P: bounds= 100+% of min & max of P
create 4 temporary centroids, TP
for p in P:
	adjust TP so that they're mirroring p across the boundary lines, top,bottom,left,right
	PP=P+TP
	others= manhattan-distance from p sorted list of centroids in PP who aren't p
	notClosed=True
	B= empty list
	while list of others isn't empty, and notClosed:
		pp= others.pop(the next nearest to p)
		b= Border(p,pp)
		for bb in B:
			v= intersect(b,bb)
			if v:
				t= Trisect(v,PP)
				if t:
					centroids in t are adjacent each other
					v is a vert of boundary of each centroid in t
					note that b and bb have each intersected another boundary once or twice

		add b to B
		if all borders in B have trisected twice, notClosed=False


Many operations are the same in reverse. Border(p1,p2)==Border(p2,p1). Intersect(b1,b2)==Intersect(b2,b1)


Trisect test is d2-d1<epsilon and d3-d2<epsilon, for dists d1,d2,d3 from point, testing all points of PP, which includes the temporary boundary centroids. I been using epsilon=1e-04, with P=rnd(1024.0)
Trisect can return the three centroid regions it divides. They neighbor each other. You might note a neighbor of None or NILL for a temporary centroid


Next is to add the points of the diagonal line segment of each border which passes a bisect test, similar to the trisect test
Sequencing each centroid's polie's verts is simple to do by sorting the angle from centroid to vert. "Winding order", clockwise or ccw, can also be tested to see if you need to reverse a poly, for collision or hardware rendering or whatever.

if you need to know which vert pair of a notClosed poly is the opening, bisect test (v1+v2)/2. 

About

In Taxi, aka Manhattan metric Voronoi, creates polygons for centroids


Languages

Language:Python 99.1%Language:Shell 0.9%