def checkLoS(self, points): """Determine line of sight between all points in the list by constructing a line segment for the two points in question and comparing it for intersection with line segments in the BSP tree :param points: a list of Point objects :return: a list of lists, n by n, an entry at [i][j] tells wether point i and point j have line of sight with each other """ LoS = [] for point in points: LoS.append(['X'] * len(points)) for FromIndex, FromPoint in enumerate(points): for ToIndex, ToPoint in enumerate(points): # if LoS is not determined if (FromIndex != ToIndex) and (LoS[FromIndex][ToIndex] == 'X'): # Assume there is LoS LoS[FromIndex][ToIndex] = 'T' LoS[ToIndex][FromIndex] = 'T' SightSegment = LineSegment( points[FromIndex], points[ToIndex]) # Point to root node stack = [self.tree] IsIntersection = False # NumOfIntersections = 0 NumOfTraversals = 0 while len(stack) != 0 and IsIntersection == False: TreePointer = stack.pop() NumOfTraversals += 1 compareLoS = TreePointer.data[0].compare(SightSegment) if compareLoS == 'P': if SightSegment.split(TreePointer.data[0]) is not None: LoS[FromIndex][ToIndex] = 'F' LoS[ToIndex][FromIndex] = 'F' else: if TreePointer.left is not None: stack.append(TreePointer.left) if TreePointer.right is not None: stack.append(TreePointer.right) elif compareLoS == 'F': if TreePointer.left is not None: stack.append(TreePointer.left) elif compareLoS == 'B': if TreePointer.right is not None: stack.append(TreePointer.right) distance = points[FromIndex].getDistance(points[ToIndex]) if IsIntersection: print(('Distance: %0.1f' % distance) + ', # of traversals(F): ' + str(NumOfTraversals)) else: print(('Distance: %0.1f' % distance) + ', # of traversals(T): ' + str(NumOfTraversals)) return LoS
def generateRandomScene( n, width, height, MinLength=50, MaxLength=300, isUniform=True): """ Randomnly generates a list of non intersecting line segments :param n: int, Number of line segments :param width: int, our area width :param height: int, our area height :param MinLength: float, Minimum possible length of a line segment :param MaxLength: float, Maximum possible length of a line segment :param isUniform: boolean, whether the position of line segments should be generated with uniform distributed random number or with powerlaw distribution :return: a list of line segments """ Lines = [] for i in range(n): Done = False while not Done: P2x = -1 P2y = -1 c = 0 if isUniform: P1x = int(round(np.random.uniform(0, width))) P1y = int(round(np.random.uniform(0, height))) Distance = np.random.uniform(MinLength, MaxLength) while not 0 <= P2x <= width: c = np.random.uniform(-1, 1) P2x = P1x + int(round(c * Distance)) while not 0 <= P2y <= height: P2y = P1y + \ int(round(sign(np.random.uniform(-1, 1)) * (1 - (abs(c))) * Distance)) else: P1x = int(round(np.random.power(3.0) * width)) P1y = int(round(np.random.power(3.0) * height)) Distance = np.random.uniform(MinLength, MaxLength) while not 0 <= P2x <= width: c = np.random.uniform(-1, 1) P2x = P1x + int(round(c * Distance)) while not 0 <= P2y <= height: P2y = P1y + \ int(round(sign(np.random.uniform(-1, 1)) * (1 - (abs(c))) * Distance)) r = round(generateRandom(1, 1)) if r == 0: r = -1 NewLine = LineSegment(Point(P1x, P1y), Point(P2x, P2y), r) IsIntersection = False for line in Lines: if NewLine.split(line) is not None: IsIntersection = True break if not IsIntersection: Lines.append(NewLine) Done = True return Lines