Beispiel #1
0
def getAngle(r1, r2):
	"""
	returns the smallest positive radian angle between two rays [p11,p12], [p21,p22]

	not fully tested
	"""
	ray1=np.array(r1)
	ray2=np.array(r2)
	inters,p=col.linesIntersect(ray1,ray2, getPoint=True)
	if inters:
		pts=[r1[0],r1[1], r2[0], r2[1]]
		if not tuple(p) in pts: raise Exception('lines are intersecting and not incident, angle not defined')
	p=np.array(p)
	points=[]
	for ray in ray1,ray2:
		furthestDist=-1
		for point in ray:
			dist=getDistance(p,point)
			if dist>furthestDist:
				furthest=point
				furthestDist=dist
		points.append(point)
	p1=np.array(points[0])-p
	p2=np.array(points[1])-p
	th=acos(np.dot(p1,p2)/(getDistance(p,p1)*getDistance(p,p2)))
	if th>pi:
		if th>2*pi: raise Exception('something is wrong with getAngle')
		th=pi-th
	return th
Beispiel #2
0
	def getPos(self):
		#returns middle of road
		if not self.endPoints: #find intersection of nodes..
			r1=np.array([self.nodes[0], self.nodes[2]])
			r2=np.array([self.nodes[1], self.nodes[3]])
			tmp, pos=col.linesIntersect(r1,r2, getPoint=True)
			pos=list(pos)
		else:
			
			p2=np.array(self.endPoints[1])
			d=np.array(self.endPoints[0])-p2
			pos=list(p2+0.5*d)
		return pos
Beispiel #3
0
def getAngle(r1, r2):
	"""
	returns the smallest positive radian angle between two rays [p11,p12], [p21,p22]

	not fully tested
	"""
	ray1=np.array(r1)
	ray2=np.array(r2)
	inters,p=col.linesIntersect(ray1,ray2, getPoint=True)
	if np.isnan(p[0]):
		return pi #parallel rays. Angle defined as pi, not 0
	if inters:
		pts=[r1[0],r1[1], r2[0], r2[1]]
		found=False
		for ptmp in pts:
			if getDistance(p, ptmp)<0.001:
				found=True
				break
		if not found:
			raise Exception('lines are intersecting and not incident, angle not defined')
	p=np.array(p)
	points=[]
	for ray in ray1,ray2:
		furthestDist=-1
		for point in ray:
			dist=getDistance(p,point)
			if dist>furthestDist:
				furthest=point
				furthestDist=dist
		points.append(point)
	p1=np.array(points[0])-p
	p2=np.array(points[1])-p
	#due to round-off errors, we get a domain error if e.g. arg=-1.000000000001. thus round
	arg=np.dot(p1,p2)/(np.linalg.norm(p1)*np.linalg.norm(p2))
	th=acos(round(arg,7))
	if th>pi:
		if th>2*pi: raise Exception('something is wrong with getAngle')
		th=2*pi-th
	assert th>=0
	return th
Beispiel #4
0
def findIntersection(origin, th, areaPoly):
	"""
	returns the intersection between the ray from origin with angle th and areaPoly. Assumes convex polygon.
	"""
	inf=1e4
	#find intersection with areaPoly
	p1=getCartesian([0, inf], origin=origin, direction=th, fromLocalCart=True)
	p2=list(origin)#getCartesian([0, 0.1], origin=origin, direction=th, fromLocalCart=True) #should be inside polygon
	ray=np.array([p1,p2])
	last=areaPoly[-1]
	point=None
	for p in areaPoly:
		borderRay=np.array([last,p])
		int, pInt=col.linesIntersect(borderRay, ray, getPoint=True) 
		if int:
			point=pInt
			break #we have found intersection point
		last=p
	if point==None:
		print "areaPoly:", areaPoly
		raise Exception('line has no intersection with polygon area')
	return tuple(point)
Beispiel #5
0
	def __init__(self,L=24, diagonals=False, angle=None, areaPoly=None, origin=None, globalOrigin=None, thMin=pi/7.):
		C=L/2.
		ExtendedGraph.__init__(self, origin=origin, globalOrigin=globalOrigin,areaPoly=areaPoly, L=L, C=C,gridtype='spiderGridGraph')
		G=self #remove later and change to self below.
		longest=L*1.4 #longest allowed distance between two nodes on a line.
		eqL=L/6. #length where two points should be merged to one,m which is done in some cases
		if not areaPoly: #use default
			areaPoly=[(0,0), (300,0), (200,300), (-100, 200)]
			if origin: raise Exception('if origin is given, so must areaPoly be...')
			origin=(0,0)
			if not origin in areaPoly: raise Exception('only origin at borderpoints supported right now ')
		else:
			if not origin:
				origin=(0,0)
			if not col.pointInPolygon(origin,areaPoly):
				raise Exception('so far, SpiderGrid only supports origins on one of the border points')
		#so, look if origin is on the lines... if it is, swift it just a bit.
		if pointOnPolygonBorder(origin, areaPoly):
			while True: #we should never be stuck in this loop. 
				xnew=round(random.uniform(-0.1,0.1),2)
				ynew=round(random.uniform(-0.1, 0.1),2)
				pnew=(origin[0]+xnew, origin[1]+ynew)
				if col.pointInPolygon(pnew, areaPoly):
					if not pointOnPolygonBorder(pnew, areaPoly):
						origin=pnew #we found our new one.
						self.origin=origin
						break
		lines=[]
		thMin*=2 #will be divided below
		while len(lines)<2:
			thMin*=0.5
			lines, baseL, baseR, orderMax=makeLines(areaPoly, origin, L, C, thMin)
		#make grid of lines.
		print "lines done, now make grid"

		el=0 #will later be filled.
		G.L=L
		G.overlap={} #will later be filled.
		#make a road segments to the ones "to the left". If road that ist drawn to is of higher order, that is the last one from this line.
		for index, line in enumerate(lines): #make line to the ones on the "left"
			if line==baseL: break
			occured=[] #a list of different orders that have occured.. pretty complex.
			#an order 1 line should not e.g. have lines to all order 4 lines to the left, only one.
			for left in lines[index+1:]: # the one to the left of "line"
				if line.order==1 and left.order==1: break
				#identify the point, p2. line between should be orthogonal to "line" or "left", depending on order.
				cont=False #continue...
				for o in occured:
					if o<=left.order: cont=True #strange procedure, but can't use "continue" here due to above for.
				if cont: continue #we jump over some lines..think about it and you'll udnerstand
				occured.append(left.order)
				if left.order>line.order: #make ray orthogonal to line

					p1=left.p1
					th2=line.angle-pi/2.
					pTmp=tuple(getCartesian([0, 10000], origin=p1, direction=th2, fromLocalCart=True))
					a, p2=col.linesIntersect(np.array([p1,pTmp]), np.array(line.ray), getPoint=True)
					if not a:
						p2=line.p2
					p2=tuple(p2)
					if not p2 in line.gridPoints:
						line.gridPoints.append(p2)
				else: #make it orthogonal to left
					p1=line.p1
					th2=left.angle+pi/2.
					pTmp=tuple(getCartesian([0, 10000], origin=p1, direction=th2, fromLocalCart=True))
					a, p2=col.linesIntersect(np.array([p1,pTmp]), np.array(left.ray), getPoint=True)
					if not a:
						p2=left.p2
					p2=tuple(p2)
					if not p2 in left.gridPoints:
						left.gridPoints.append(p2)
				if not a:
					pass #raise Exception('something wrong, did not find neighbor point')
				if G.has_node(p1):
					G.add_node(p1)
					el+=1
				if not p2 in G.nodes():
					G.add_node(p2)
					el+=1
				G.add_edge(p1,p2, weight=self.edgeWeightCalc(p1,p2), visits=0, visited_from_node=[], c=0)
				if left.order <= line.order: break
		print "add neighbors"
		#we have the pattern. Add edges to neighbors in not that dens regions
		for index,line in enumerate(lines): 	#end points. Usually between two endpoints but not always.
			if line.no==baseL.no: break #this is the end
			leftBuddy=lines[index+1]
			if leftBuddy.angle<line.angle: raise Exception('ordering wrong..')
			closest=leftBuddy.gridPoints[0]
			closDist=getDistance(closest, line.p2)
			for pTmp in leftBuddy.gridPoints[1:]:
				d=getDistance(pTmp, line.p2)
				if d<closDist:
					closDist=d
					closest=pTmp
			G.add_edge(line.p2, closest, weight=self.edgeWeightCalc(line.p2, closest), visits=0, visited_from_node=[], c=0)
		lOrdered=copy.copy(lines) #not deepcopy, line instances are the same
		lOrdered=sorted(lOrdered, key=lambda line: line.order)
		for line in lOrdered:
			#if line.no==baseL.no: continue
			#now, identify the potential neighbors first.
			candidatesL=[]
			candidatesR=[]
			for cand, left in [(candidatesL, True), (candidatesR, False)]: #left=True if left.. faster
				for o in range(orderMax+1):
					if o==0: continue
					lst=[]
					if left:
						lst=[l for l in lines if l.order==o and l.angle>line.angle]
						nearest=None
						minAng=1e10
						for l in lst:
							if l.angle<minAng:
								nearest=l
								minAng=nearest.angle
						if nearest: cand.append(nearest) #we have our candidate of this order.
					else:
						lst=[l for l in lines if l.order==o and l.angle<line.angle]
						nearest=None
						maxAng=-1e10
						for l in lst:
							if l.angle>maxAng:
								nearest=l
								maxAng=nearest.angle
						if nearest: cand.append(nearest) #we have our candidate of this order.
			line.gridPoints=sorted(line.gridPoints, key=lambda point: -getDistance(point, origin)) #closest first
			last=line.gridPoints[0]
			for pTmp in copy.copy(line.gridPoints[1:]):
				d=getDistance(last,pTmp)
				if d>longest:
					nPoints=int(ceil(d/longest))-1
					last=pTmp
					l=d/(nPoints+1) #distance between points
					for i in range(nPoints):
						p=tuple(getCartesian([0, (i+1)*l], origin=pTmp, direction=line.angle, fromLocalCart=True))
						candidatesL=sorted(candidatesL, key=lambda l: abs(l.angle-line.angle))
						candidatesR=sorted(candidatesR, key=lambda l: abs(l.angle-line.angle))
						leftRay=np.array([p, getCartesian([0,100], origin=p, direction=line.angle+pi/2., fromLocalCart=True)])
						rightRay=np.array([p, getCartesian([0,100], origin=p, direction=line.angle-pi/2., fromLocalCart=True)])
						pL=None
						pR=None
						for cand in candidatesL:
							a,p2=col.linesIntersect(np.array(cand.ray), leftRay, getPoint=True)
							if a: #cand:s are ordered so that this is "the one"
								for pT in cand.gridPoints:
									if getDistance(list(pT), p2)<eqL: #2 meters.. same
										p2=pT
										break
								pL=tuple(p2)
								if not pL in cand.gridPoints: cand.gridPoints.append(pL)
								break
						for cand in candidatesR:
							a,p2=col.linesIntersect(np.array(cand.ray), rightRay, getPoint=True)
							if a: #cand:s are ordered so that this is "the one"
								for pT in cand.gridPoints:
									if getDistance(list(pT), p2)<eqL: #2 meters.. same
										p2=pT
										break
								pR=tuple(p2)
								if not pR in cand.gridPoints: cand.gridPoints.append(pR)
								break
						#now, if both pL and pR, create a straight line.
						if pL and pR: #new p!
							a,p=col.linesIntersect(np.array(line.ray), np.array([pL,pR]), getPoint=True)
							if not a: raise Exception('expected to find p here..')
							p=tuple(p)
						if pL:
							G.add_edge(pL,p,weight=self.edgeWeightCalc(pL,p), visits=0, visited_from_node=[], c=0)
						if pR:
							G.add_edge(pR,p, weight=self.edgeWeightCalc(pR,p), visits=0, visited_from_node=[], c=0)
						if not pL and not pR:
							G.add_node(p)
						line.gridPoints.append(tuple(p))
						
				last=pTmp

		for line in lines: #add edges on the line
			if len(line.gridPoints)<=1: continue
			line.gridPoints=sorted(line.gridPoints, key=lambda point: -getDistance(point, origin))
			last=line.gridPoints[0]
			for node in line.gridPoints[1:]:
				G.add_edge(last, node,weight=self.edgeWeightCalc(last, node), visits=0, visited_from_node=[], c=0)
				last=node
		rem=True
		for n in self.nodes():
			if not self.inside(n):
				self.remove_node(n)
		while rem:
			rem=False
			for n in self.nodes(): #pretty ugly, but a must..
				if self.degree(n)<=1:
					rem=True
					self.remove_node(n)
					break
		self.overlap={} #will later be filled.
		self.roadWidth=4
		self.L=L
		if not self.origin in self.nodes():
			shortest=None
			short_dist=1e10
			for n in self.nodes():
				d=fun.getDistance(n, self.origin)
				if d<short_dist:
					short_dist=d
					shortest=n
			self.origin=shortest
		elements=len(self.nodes())
		self.elements=elements
		self.density=elements/self.A
		self.density=elements/self.A