Example #1
0
def pointOnPolygonBorder(point, poly):
	"""
	determines if point is on border of polygon
	"""
	last=poly[-1]
	for node in poly:
		ray=[last, node]
		if col.pointOnLine(ray, point):
			return True
		last=node
	return False
Example #2
0
def makeLines(areaPoly, origin, L, C, thMin):
	"""
	given an origin and an areaPolygon, this function creates lines from a specific spidernet pattern.
	"""
	#first, determine if origin is on border lines.
	if pointOnPolygonBorder(origin,areaPoly) or not col.pointInPolygon(origin, areaPoly): raise Exception('origin has to be inside polygon')
	xnorm=[origin, (origin[0]+1, origin[1])] #xaxis, used for angle calc.
	baseL=None #standard value until determined
	baseR=None

	if origin in areaPoly: #origin is on intersection
		for i in range(len(areaPoly)): #find origin
			if areaPoly[i]==origin:
				origInd=i
		ray1=[areaPoly[origInd], areaPoly[origInd-1]]
		ray2=[areaPoly[origInd], areaPoly[origInd+1]]
		baseL=Line(ray1[0], ray1[1], getAngle(ray1, xnorm), order=1)
		baseR=Line(ray2[0], ray2[1], getAngle(ray2, xnorm), order=1)
	else: #see if it is on border lines
		last=areaPoly[-1]
		for node in areaPoly:
			ray=[last, node]
			if col.pointOnLine(ray, origin):
				"""
				something is wrong with the angles below. Change to vectors so we get different angles.
				"""
				ray1=[origin, ray[0]]
				ray2=[origin, ray[1]]
				baseL=Line(ray1[0], ray1[1],  angleToXAxis(ray1), order=1)
				baseR=Line(ray2[0], ray2[1], angleToXAxis(ray2), order=1)
				break
			last=node


	if baseL==None: #origin is inside areaPoly. Make x-axis baseL and baseR
		p2=findIntersection(list(origin), th=0, areaPoly=areaPoly)
		baseL=Line(origin, p2, angle=2*pi, order=1)
		baseR=Line(origin, p2, angle=0, order=1)  #smart, huh? :)
	else:	#so, we have the bases.. check if left and right is correct
		if baseL.angle<baseR.angle:
			tmp=baseL
			baseL=baseR
			baseR=tmp
		angle=baseL.angle-asin(L*0.5/getDistance(baseL.ray[0], baseL.ray[1]))
		p2=findIntersection(list(baseL.p1), angle, areaPoly)
		cyl=getCylindrical(p2, origin=origin) #take it further away from the border
		p2=getCartesian([cyl[0]-C, cyl[1]], origin=origin)
		baseL=Line(p1=baseL.p1, p2=p2, angle=angle, order=baseL.order)
	
		angle=baseR.angle+asin(L*0.5/getDistance(baseR.ray[0], baseR.ray[1]))
		p2=findIntersection(list(baseR.p1), angle, areaPoly)
		cyl=getCylindrical(p2, origin=origin) #take it further away from the border
		p2=getCartesian([cyl[0]-C, cyl[1]], origin=origin)
		baseR=Line(p1=baseR.p1, p2=p2, angle=angle, order=baseL.order)
	print "base lines are done..."
	lines=[baseR, baseL]
	th=baseL.angle-baseR.angle
	dth=th
	order=1
	while True: #create lines, base roads
		dth=dth/2.
		if dth<thMin: break
		#order+=1
		newList=copy.deepcopy(lines)
		for i in range(len(lines)): #iterate through, from right to left
			line=lines[i]
			if line.no != baseL.no:
				th=line.angle+dth
				point=findIntersection(origin, th, areaPoly)
				cyl=getCylindrical(point, origin=origin) #take it further away from the border
				if cyl[0]<=C: continue #line is very short, not worth it.
				point=getCartesian([cyl[0]-C, cyl[1]], origin=origin)
				lnew=Line(origin, point, th, order=order)
				for ind,ltmp in enumerate(newList):
					if ltmp.no==line.no:
						newList.insert(ind+1, lnew)
						break
		lines=newList
	#the base roads are done.. now let's find the smaller lines.
	lines.remove(lines[-1]) #this is baseL..same as baseR, remember?
	baseL=lines[-1] #the one most to the left
	#strategy: insert a line between two lines as long as asin(0.5L/length(line))>L
	while True:
		added=False
		newList=copy.deepcopy(lines)
		order+=1
		for i in range(len(lines)): #iterate through, from right to left
			line=lines[i]
			if line.no != baseL.no:
				leftBuddy=lines[i+1] #the one "to the left"
				rightBuddy=line
				#in the future, taking terrain into consideration, the angles to left and right buddy wont be the same. But now they are.
				dth=(leftBuddy.angle-rightBuddy.angle)/2. #the angle between..
				th=rightBuddy.angle+dth #angle in rel. to xaxis
				point=findIntersection(origin, th, areaPoly) #point at other side of areaPoly
				#now, make it C distance away from border.
				cyl=getCylindrical(point, origin=origin)
				point=getCartesian([cyl[0]-C, cyl[1]], origin=origin)
				d=getDistance(origin, point)
				if d/tan(dth)>L:
					#this means that it will be reasonable to place a grid point on line. Create line!
					y=0.5*L*(1+1/sin(dth))#/(sin(dth)**2)
					p1=getCartesian([0, y], fromLocalCart=True, origin=origin, direction=th) #where it all starts..
					if getDistance(p1, origin)>=d or getDistance(p1,point)<C:
						continue #don't make line, it has a "negative length" or is too short..
					if col.pointInPolygon(p1, areaPoly):
						lnew=Line(p1, point, th, order=order)
						for ind,ltmp in enumerate(newList):
							if ltmp.no==line.no:
								added=True
								newList.insert(ind+1, lnew)
		if not added: break #no more lines to add.
		lines=newList
	return lines, baseL, baseR, order