Esempio n. 1
0
    def find_intersect(self, other: 'Segment') -> Optional[Intersection]:
        """
        Gets the Intersection between this and another road if they intersect or if this road can be extended
        to intersect with it
        :param other: Another Segment to check for an intersection with
        :return: An Intersection tuple with the point and the factors for each road
        """
        r = vectors.sub(self.end, self.start)
        s = vectors.sub(other.end, other.start)

        t_numerator = vectors.cross_product(
            vectors.sub(other.start, self.start), s)
        u_numerator = vectors.cross_product(
            vectors.sub(other.start, self.start), r)
        denominator = vectors.cross_product(r, s)

        if denominator == 0:
            return None
        this_factor = t_numerator / denominator
        other_factor = u_numerator / denominator

        if 0 < other_factor < 1:
            return Intersection(
                (self.start[0] + (this_factor * r[0]), self.start[1] +
                 (this_factor * r[1])), this_factor, other_factor)

        return None
Esempio n. 2
0
def offset_point(point, rotate_function, offset_length, predecessor,
                 successor):
    pre_offset_vector = None
    suc_offset_vector = None
    if predecessor:
        pre_direction = vectors.unit(vectors.sub(point, predecessor))
        pre_offset_vector = vectors.mult(rotate_function(pre_direction),
                                         offset_length)
    if successor:
        suc_direction = vectors.unit(vectors.sub(successor, point))
        suc_offset_vector = vectors.mult(rotate_function(suc_direction),
                                         offset_length)

    if predecessor and successor:
        return intersection((vectors.add(predecessor, pre_offset_vector),
                             vectors.add(point, pre_offset_vector)),
                            (vectors.add(point, suc_offset_vector),
                             vectors.add(successor, suc_offset_vector)))
    elif predecessor:
        return vectors.add(point, pre_offset_vector)
    elif successor:
        return vectors.add(point, suc_offset_vector)
    else:
        raise Exception(
            'at least one of predecessor and successor have to be set')
Esempio n. 3
0
def angle_between_ccw(road1: Segment, road2: Segment) -> float:
    """
    Gets the angle between road1 and road2 in a counterclockwise direction
    """

    if road1.start == road2.start:
        vect1 = vectors.sub(road1.end, road1.start)
        vect2 = vectors.sub(road2.end, road1.start)
    elif road1.start == road2.end:
        vect1 = vectors.sub(road1.end, road1.start)
        vect2 = vectors.sub(road2.start, road1.start)
    elif road1.end == road2.start:
        vect1 = vectors.sub(road1.start, road1.end)
        vect2 = vectors.sub(road2.end, road1.end)
    elif road1.end == road2.end:
        vect1 = vectors.sub(road1.start, road1.end)
        vect2 = vectors.sub(road2.start, road1.end)

    dot = vectors.dot(vect1, vect2)
    det = vectors.determinant(vect1, vect2)

    deg = math.degrees(math.atan2(det, dot))

    if -180 <= deg <= 0:
        deg += 360

    return deg
Esempio n. 4
0
def closest_analogies(
    left2: str, left1: str, right2: str, words: List[Word]
) -> List[Tuple[float, Word]]:
    word_left1 = find_word(left1, words)
    word_left2 = find_word(left2, words)
    word_right2 = find_word(right2, words)
    if (not word_left1) or (not word_left2) or (not word_right2):
        return []
    vector = v.add(
        v.sub(word_left1.vector, word_left2.vector),
        word_right2.vector)
    closest = most_similar(vector, words)[:10]
    def is_redundant(word: str) -> bool:
        """
        Sometimes the two left vectors are so close the answer is e.g.
        "shirt-clothing is like phone-phones". Skip 'phones' and get the next
        suggestion, which might be more interesting.
        """
        word_lower = word.lower()
        return (
            left1.lower() in word_lower or
            left2.lower() in word_lower or
            right2.lower() in word_lower)
    closest_filtered = [(dist, w) for (dist, w) in closest if not is_redundant(w.text)]
    return closest_filtered
Esempio n. 5
0
    def point_at(self, factor: float) -> Tuple[float, float]:
        """
        Gets the point along the road (length * factor) away from the start
        :param factor: Fraction of the way down the road, between 0 and 1
        :return: The point along the road
        """
        end_vector = vectors.sub(self.end, self.start)

        return self.start[0] + (factor * end_vector[0]), self.start[1] + (
            factor * end_vector[1])
Esempio n. 6
0
    def _zoom_change(self, step, center):
        new_level = self._zoom_at(self._zoom_increment + step)

        old_world = screen_to_world(center, self.pan, self.zoom)
        new_world = screen_to_world(center, self.pan, new_level)

        world_pan = vectors.sub(new_world, old_world)

        self.zoom = new_level
        self.pan = vectors.add(self.pan, world_to_screen(world_pan, (0, 0), new_level))

        self._zoom_increment += step
        return
Esempio n. 7
0
def from_seg(segment: roads.Segment) -> Set[Tuple[int, int]]:
    """ Gets the sectors the segment is in or within snapping distance of """
    start_sector = containing_sector(segment.start)
    end_sector = containing_sector(segment.end)

    aux_secs = set()

    if start_sector[0] != end_sector[0] and start_sector[1] != end_sector[1]:
        diff = vectors.sub(start_sector, end_sector)
        aux_secs.add((end_sector[0] + diff[0], end_sector[1]))
        aux_secs.add((end_sector[0], end_sector[1] + diff[1]))

    start_secs = from_point(segment.start, config.MIN_DIST_EDGE_CONTAINED)
    end_secs = from_point(segment.end, config.MIN_DIST_EDGE_CONTAINED)

    return start_secs.union(end_secs).union(aux_secs)
def closest_analogies(left2: str, left1: str, right2: str,
                      words: List[Word]) -> List[Tuple[float, Word]]:
    word_left1 = find_word(words, left1)
    word_left2 = find_word(words, left2)
    word_right2 = find_word(words, right2)
    vector = v.add(v.sub(word_left1.vector, word_left2.vector),
                   word_right2.vector)
    closest = sorted_by_similarity(words, vector)[:10]

    def is_redundant(word: str) -> bool:
        #Sometimes the two left vectors are so close the answer is e.g.
        #"shirt-clothing is like phone-phones". Skip 'phones' and get the next
        #suggestion, which might be more interesting.
        return (left1.lower() in word.lower() or left2.lower() in word.lower()
                or right2.lower() in word.lower())

    return [(dist, w) for (dist, w) in closest if not is_redundant(w.text)]
Esempio n. 9
0
 def update(self):
     #self.rect.y -= 1
     target_vector = v.sub(self.target, self.pos) 
     move_vector = [c * self.speed for c in v.normalize(target_vector)]
     self.x, self.y = v.add(self.pos, move_vector)
     self.rect.x = self.x
     self.rect.y = self.y
     for wall in walls:
         if self.rect.colliderect(wall.rect):
             if self.rect.x > 0: # Moving right; Hit the left side of the wall
                 self.rect.right = wall.rect.left
             if self.rect.x < 0: # Moving left; Hit the right side of the wall
                 self.rect.left = wall.rect.right
             if self.rect.y > 0: # Moving down; Hit the top side of the wall
                 self.rect.bottom = wall.rect.top
             if self.rect.y < 0: # Moving up; Hit the bottom side of the wall
                 self.rect.top = wall.rect.bottom
Esempio n. 10
0
def main():
    pygame.init()
    drawing.init()

    screen_data = drawing.ScreenData(
        pygame.display.set_mode(config.SCREEN_RES, pygame.RESIZABLE), (0, 0))
    input_data = InputData()
    path_data = pathing.PathData()
    selection = None

    lots = []

    city = generation.generate()
    city_labels = []
    for road in city.roads:
        city_labels.append((str(road.global_id), road.point_at(0.5)))

    prev_time = pygame.time.get_ticks()

    running = True
    while running:
        if pygame.time.get_ticks() - prev_time < 16:
            continue

        input_data.pos = pygame.mouse.get_pos()
        input_data.pressed = pygame.mouse.get_pressed()
        prev_time = pygame.time.get_ticks()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.VIDEORESIZE:
                screen_data.screen = pygame.display.set_mode(
                    event.dict["size"], pygame.RESIZABLE)
                config.SCREEN_RES = event.dict["size"]
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_g:
                    debug.SHOW_ROAD_ORDER = False
                    city_labels = []
                    selection = None
                    path_data = pathing.PathData()
                    city = generation.generate()
                    for road in city.roads:
                        city_labels.append(
                            (str(road.global_id), road.point_at(0.5)))
                if event.key == pygame.K_b:
                    lots = build_gen.gen_lots(city)
                # Pathing
                elif event.key == pygame.K_z:
                    path_data.start = road_near_point(input_data.pos,
                                                      screen_data, city)
                elif event.key == pygame.K_x:
                    path_data.end = road_near_point(input_data.pos,
                                                    screen_data, city)
                elif event.key == pygame.K_c:
                    pathing.astar(path_data, city.roads)
                elif event.key == pygame.K_v:
                    pathing.dijkstra(path_data, city.roads)
                # Debug Views
                else:
                    handle_keys_debug(event.key)
            elif event.type == pygame.MOUSEBUTTONDOWN:
                # Zooming
                if event.button == 4:
                    screen_data.zoom_in(input_data.pos)
                elif event.button == 5:
                    screen_data.zoom_out(input_data.pos)

        # Dragging & Selection
        if input_data.prev_pressed[0]:
            if input_data.pressed[0]:  # Continue drag
                screen_data.pan = vectors.add(
                    screen_data.pan,
                    vectors.sub(input_data.pos, input_data.drag_prev_pos))
                input_data.drag_prev_pos = input_data.pos
            else:
                if input_data.pos == input_data.drag_start:  # Select road
                    selection = selection_from_road(
                        road_near_point(input_data.drag_start, screen_data,
                                        city))
                # Clear out drag information
                input_data.drag_start = None
                input_data.drag_prev_pos = (0, 0)
        else:
            if input_data.pressed[0]:  # Drag started
                input_data.drag_start = input_data.pos
                input_data.drag_prev_pos = input_data.pos

        # Drawing
        screen_data.screen.fill((0, 0, 0))
        if debug.SHOW_HEATMAP:
            drawing.draw_heatmap(50, city, screen_data)
        if debug.SHOW_SECTORS:
            drawing.draw_sectors(screen_data)

        color = (125, 255, 50)
        for poly in lots:
            temp = []
            for point in poly:
                temp.append(
                    drawing.world_to_screen(point, screen_data.pan,
                                            screen_data.zoom))
            pygame.draw.polygon(screen_data.screen, color, temp)
            color = (color[0], color[1] - 11, color[2] + 7)
            if color[1] < 0:
                color = (color[0], 255, color[2])
            if color[2] > 255:
                color = (color[0], color[1], 0)

        # Draw roads
        if debug.SHOW_ISOLATE_SECTOR and selection is not None:
            for sector in sectors.from_seg(selection.road):
                drawing.draw_all_roads(city.sectors[sector], screen_data)
        elif debug.SHOW_MOUSE_SECTOR:
            mouse_sec = sectors.containing_sector(
                drawing.screen_to_world(input_data.pos, screen_data.pan,
                                        screen_data.zoom))
            if mouse_sec in city.sectors:
                drawing.draw_all_roads(city.sectors[mouse_sec], screen_data)
        else:
            tl_sect = sectors.containing_sector(
                drawing.screen_to_world((0, 0), screen_data.pan,
                                        screen_data.zoom))
            br_sect = sectors.containing_sector(
                drawing.screen_to_world(config.SCREEN_RES, screen_data.pan,
                                        screen_data.zoom))
            for x in range(tl_sect[0], br_sect[0] + 1):
                for y in range(tl_sect[1], br_sect[1] + 1):
                    if (x, y) in city.sectors:
                        drawing.draw_all_roads(city.sectors[(x, y)],
                                               screen_data)

        drawing.draw_roads_selected(selection, screen_data)
        drawing.draw_roads_path(path_data, screen_data)

        if debug.SHOW_INFO:
            debug_labels = debug.labels(screen_data, input_data, path_data,
                                        selection, city)

            for x in range(len(debug_labels[0])):
                label_pos = (10, 10 + x * 15)
                drawing.draw_label_screen((debug_labels[0][x], label_pos),
                                          screen_data, 1)

            for x in range(len(debug_labels[1])):
                label_pos = (config.SCREEN_RES[0] - 10, 10 + x * 15)
                drawing.draw_label_screen((debug_labels[1][x], label_pos),
                                          screen_data, -1)

        if debug.SHOW_ROAD_ORDER:
            for label in city_labels:
                drawing.draw_label_world(label, screen_data, 1)

        pygame.display.flip()