Exemple #1
0
def make_rivers(world):
    """ Make rivers """
    # a 2D array of values at each pixel representing the amount of water that has flowed through
    # this pixel into a neighbor
    rainflow = np.zeros(world["heightmap"].shape, dtype=int)

    # a working array that represents the rain flow after a certain number of calls to flow()
    waterlevel = np.zeros(world["heightmap"].shape, dtype=int)

    # an array of (x, y) coordinates of the nearest lowest neighbor
    lowest_neighbors = np.empty(world["heightmap"].shape, dtype="int, int")

    x_, y_ = rainflow.shape
    for x in xrange(x_):
        for y in xrange(y_):
            altitude = world["heightmap"][x, y]
            if altitude > world["sea_level"]:
                rainflow[x, y] = 1
                waterlevel[x, y] = 1
                their_altitude, t_x, t_y = find_neighbors(world["heightmap"], (x, y), sort=True)[0]
                if their_altitude < world["heightmap"][x, y]:
                    lowest_neighbors[x, y] = (t_x, t_y)

    print(lowest_neighbors[10, 10])

    def flow():
        x_, y_ = rainflow.shape
        for x in xrange(x_):
            for y in xrange(y_):
                if waterlevel[x, y] != 0:  # land pixels
                    # get the lowest neighbor
                    n = lowest_neighbors[x, y]

                    # is the lowest neighbor less than me?
                    if n:
                        # move my water to the neighbor
                        waterlevel[n[0], n[1]] += waterlevel[x, y]
                        # rainflow[n[0], n[1]] += waterlevel[x, y]
                        waterlevel[x, y] = 0

    for i in xrange(3):
        print("Flow %i" % i)
        flow()

    return waterlevel
Exemple #2
0
 def next(self, last_elevation=None):
     if last_elevation is None:
         last_elevation = self.elevation
     elevation, x, y = find_neighbors(self.river.world['heightmap'],
                                      self.location,
                                      sort=True)[0]
     print self.elevation, elevation, x, y
     if self.river.world['river_array'][x][y]:
         # neighbor is a river segment
         print('encountered river at ', x, y)
         return False
     # if elevation == self.elevation:
     #     print("Making a lake at %i, %i" % (x, y))
     #     lake = Lake(self.river, (x, y), self.elevation)
     #     self.next_segments.append(lake)
     #     lake.fill()
     if elevation <= last_elevation and  elevation > self.river.world['sea_level']:
         segment = RiverSegment(self.river, (x, y))
         self.next_segments.append(segment)
         segment.next(elevation)
     else:
         print('Reached sea level')
Exemple #3
0
def make_rivers(world):
    """
    Generate rivers. Returns a tuple containing:
    - River instances
    - new world dictionary, containging:
        - new heightmap after river erosion and deposition
        - river_array: numpy boolean array in shape of heightmap showing where rivers are
    """
    mountain_cutoff = world['max_height'] - 15
    mountains = np.transpose(np.nonzero(world['heightmap'] >= mountain_cutoff))
    np.random.shuffle(mountains)

    log('%i mountains or %0.5f%%' %
        (len(mountains), (float(len(mountains)) / float(world['size']**2)) * 100))

    num_rivers = randint(0, int(len(mountains) * 0.10))
    log('Making %i rivers' % num_rivers)
    river_sources = mountains[:num_rivers]

    # since rivers look the same on the images, this is a boolean array
    world['river_array'] = np.zeros(world['heightmap'].shape, dtype=np.bool)

    def get_elevation(loc):
        return world['heightmap'][loc[0], loc[1]]

    def is_river(loc):
        return world['river_array'][loc[0], loc[1]] is True

    def make_river_segment(loc):
        print(loc)
        world['river_array'][loc[0], loc[1]] = True

    rivers = []
    for source in river_sources:
        current_location = source
        current_elevation = get_elevation(current_location)
        can_continue = True
        while current_elevation >= world['sea_level'] and can_continue:


            # get neighboring pixels
            neighbors = find_neighbors(world['heightmap'],
                                       current_location,
                                       sort=True)[0]
            # lowest neighbor is higher  than me
            # if neighbors[0] > current_elevation):
            #     # make a lake here
            #     pass
            next_segment = neighbors[1], neighbors[2]
            # Is there a river here?
            if is_river(next_segment):
                print('River found at %i, %i', current_location)
                can_continue = False
            make_river_segment(current_location)
            current_location = next_segment
            current_elevation = get_elevation(current_location)

        # river = River(world, source)
        # river.flow()
        # world = river.world
        # rivers.append(river)


    return rivers, world