Struct mapgen::geometry::Rect

source ·
pub struct Rect {
    pub x1: usize,
    pub x2: usize,
    pub y1: usize,
    pub y2: usize,
}
Expand description

Rectangle region on the map

Fields§

§x1: usize§x2: usize§y1: usize§y2: usize

Implementations§

Examples found in repository?
src/geometry.rs (line 45)
44
45
46
    pub fn new_i32(x:i32, y: i32, width:i32, height:i32) -> Rect {
        Rect::new(x as usize, y as usize, width as usize, height as usize)
    }
More examples
Hide additional examples
src/filter/simple_rooms.rs (line 59)
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
    fn build_rooms(&self, map: &MapBuffer, rng : &mut StdRng) -> MapBuffer {
        let mut new_map = map.clone();

        // Create room dimensions
        for _ in 0..self.max_rooms {
            let w = rng.random_range(self.min_room_size, self.max_room_size);
            let h = rng.random_range(self.min_room_size, self.max_room_size);
            let x = rng.random_range(1, new_map.width - w);
            let y = rng.random_range(1, new_map.height - h);
            let new_room = Rect::new(x, y, w, h);
            let intersects = new_map.rooms.iter().any(|r| new_room.intersect(r));
            if !intersects {
                new_map.add_room(new_room);
            }
        }
        
        new_map
    }
src/filter/bsp_rooms.rs (line 48)
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
    fn build_rooms(&self, map: &MapBuffer, rng : &mut StdRng) -> MapBuffer {
        let mut new_map = map.clone();
        // Start with a single map-sized rectangle
        let mut rects = vec![Rect::new(2, 2, new_map.width-5, new_map.height-5)];
        let first_room = rects[0];
        rects.append(&mut self.split_into_subrects(first_room)); // Divide the first room

        // Up to max_split times, we get a random rectangle and divide it. If its possible to squeeze a
        // room in there, we place it and add it to the rooms list.
        for _ in 0..self.max_split {
            let rect = self.get_random_rect(rng, &rects);
            let candidate = self.get_random_sub_rect(rect, rng);

            if self.is_possible(candidate, &new_map) {
                new_map.add_room(candidate);
                rects.append(&mut self.split_into_subrects(rect));
            }
        }

        new_map
    }

    fn split_into_subrects(&self, rect: Rect) -> Vec<Rect> {
        let mut rects: Vec<Rect> = Vec::new();
        let width = rect.width();
        let height = rect.height();
        let half_width = usize::max(width / 2, 1);
        let half_height = usize::max(height / 2, 1);

        rects.push(Rect::new( rect.x1, rect.y1, half_width, half_height ));
        rects.push(Rect::new( rect.x1, rect.y1 + half_height, half_width, half_height ));
        rects.push(Rect::new( rect.x1 + half_width, rect.y1, half_width, half_height ));
        rects.push(Rect::new( rect.x1 + half_width, rect.y1 + half_height, half_width, half_height ));

        rects
    }
src/filter/bsp_interior.rs (line 50)
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
    fn build(&self, rng: &mut StdRng, map: &MapBuffer) -> MapBuffer {
        let mut new_map = map.clone();
        let mut rects = vec![Rect::new(1, 1, new_map.width-2, new_map.height-2)];
        let first_room = rects[0];
        // Divide the first room
        self.add_subrects(first_room, rng, &mut rects); 

        let rooms_copy = rects.clone();
        for r in rooms_copy.iter() {
            let room = *r;
            new_map.add_room(room);
        }

        // Now we want corridors
        for i in 0..new_map.rooms.len()-1 {
            let room = new_map.rooms[i];
            let next_room = new_map.rooms[i+1];
            let start_x = rng.random_range(room.x1, room.x2);
            let start_y = rng.random_range(room.y1, room.y2);
            let end_x = rng.random_range(next_room.x1, next_room.x2);
            let end_y = rng.random_range(next_room.y1, next_room.y2);
            new_map.add_corridor(Point::new(start_x, start_y), Point::new(end_x, end_y));
        }

       new_map 
    }

    fn add_subrects(&self, rect: Rect, rng: &mut StdRng, rects: &mut Vec<Rect>) {
        // Remove the last rect from the list
        if !rects.is_empty() {
            rects.remove(rects.len() - 1);
        }

        // Calculate boundaries
        let width  = rect.x2 - rect.x1;
        let height = rect.y2 - rect.y1;
        let half_width = width / 2;
        let half_height = height / 2;

        let split = rng.roll_dice(1, 4);

        if split <= 2 {
            // Horizontal split
            let h1 = Rect::new( rect.x1, rect.y1, half_width-1, height );
            rects.push( h1 );
            if half_width > self.min_room_size { self.add_subrects(h1, rng, rects); }
            let h2 = Rect::new( rect.x1 + half_width, rect.y1, half_width, height );
            rects.push( h2 );
            if half_width > self.min_room_size { self.add_subrects(h2, rng, rects); }
        } else {
            // Vertical split
            let v1 = Rect::new( rect.x1, rect.y1, width, half_height-1 );
            rects.push(v1);
            if half_height > self.min_room_size { self.add_subrects(v1, rng, rects); }
            let v2 = Rect::new( rect.x1, rect.y1 + half_height, width, half_height );
            rects.push(v2);
            if half_height > self.min_room_size { self.add_subrects(v2, rng, rects); }
        }
    }

Returns true if this overlaps with other

Examples found in repository?
src/filter/simple_rooms.rs (line 60)
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
    fn build_rooms(&self, map: &MapBuffer, rng : &mut StdRng) -> MapBuffer {
        let mut new_map = map.clone();

        // Create room dimensions
        for _ in 0..self.max_rooms {
            let w = rng.random_range(self.min_room_size, self.max_room_size);
            let h = rng.random_range(self.min_room_size, self.max_room_size);
            let x = rng.random_range(1, new_map.width - w);
            let y = rng.random_range(1, new_map.height - h);
            let new_room = Rect::new(x, y, w, h);
            let intersects = new_map.rooms.iter().any(|r| new_room.intersect(r));
            if !intersects {
                new_map.add_room(new_room);
            }
        }
        
        new_map
    }
More examples
Hide additional examples
src/filter/bsp_rooms.rs (line 114)
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
    fn is_possible(&self, rect: Rect, map: &MapBuffer) -> bool {
        let mut expanded = rect;
        expanded.x1 -= 2;
        expanded.x2 += 2;
        expanded.y1 -= 2;
        expanded.y2 += 2;

        let mut can_build = true;

        for r in map.rooms.iter() {
            if r.intersect(&rect) { can_build = false; }
        }

        for y in expanded.y1 ..= expanded.y2 {
            for x in expanded.x1 ..= expanded.x2 {
                if x > map.width - 2 { can_build = false; }
                if y > map.height - 2 { can_build = false; }
                if x < 1 { can_build = false; }
                if y < 1 { can_build = false; }
                if can_build && map.is_walkable(x as usize, y as usize) {
                    can_build = false;
                }
            }
        }

        can_build
    }
Examples found in repository?
src/filter/rooms_corridors_nearest.rs (line 29)
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
    fn corridors(&self, map: &MapBuffer) -> MapBuffer {
        let mut new_map = map.clone();

        let mut connected : HashSet<usize> = HashSet::new();
        for (i,room) in map.rooms.iter().enumerate() {
            let mut room_distance : Vec<(usize, f32)> = Vec::new();
            let room_center = room.center();
            for (j,other_room) in new_map.rooms.iter().enumerate() {
                if i != j && !connected.contains(&j) {
                    let other_center = other_room.center();
                    let distance = room_center.distance_to(&other_center);
                    room_distance.push((j, distance));
                }
            }

            if !room_distance.is_empty() {
                room_distance.sort_by(|a,b| a.1.partial_cmp(&b.1).unwrap() );
                let dest_center = new_map.rooms[room_distance[0].0].center();
                new_map.add_corridor(room_center, dest_center);
                connected.insert(i);
            }
        }
        new_map
    }
Examples found in repository?
src/filter/bsp_rooms.rs (line 69)
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
    fn split_into_subrects(&self, rect: Rect) -> Vec<Rect> {
        let mut rects: Vec<Rect> = Vec::new();
        let width = rect.width();
        let height = rect.height();
        let half_width = usize::max(width / 2, 1);
        let half_height = usize::max(height / 2, 1);

        rects.push(Rect::new( rect.x1, rect.y1, half_width, half_height ));
        rects.push(Rect::new( rect.x1, rect.y1 + half_height, half_width, half_height ));
        rects.push(Rect::new( rect.x1 + half_width, rect.y1, half_width, half_height ));
        rects.push(Rect::new( rect.x1 + half_width, rect.y1 + half_height, half_width, half_height ));

        rects
    }

    fn get_random_rect(&self, rng : &mut StdRng, rects: &[Rect]) -> Rect {
        if rects.len() == 1 { return rects[0]; }
        let idx = rng.random_range(0, rects.len());
        rects[idx]
    }

    fn get_random_sub_rect(&self, rect: Rect, rng: &mut StdRng) -> Rect {
        let mut result = rect;
        let rect_width = rect.width();
        let rect_height = rect.height();

        let w = usize::max(3, rng.random_range(1, usize::min(rect_width as usize, 20))) + 1;
        let h = usize::max(3, rng.random_range(1, usize::min(rect_height as usize, 20))) + 1;

        result.x1 += rng.random_range(0, 6);
        result.y1 += rng.random_range(0, 6);
        result.x2 = result.x1 + w;
        result.y2 = result.y1 + h;

        result
    }
Examples found in repository?
src/filter/bsp_rooms.rs (line 70)
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
    fn split_into_subrects(&self, rect: Rect) -> Vec<Rect> {
        let mut rects: Vec<Rect> = Vec::new();
        let width = rect.width();
        let height = rect.height();
        let half_width = usize::max(width / 2, 1);
        let half_height = usize::max(height / 2, 1);

        rects.push(Rect::new( rect.x1, rect.y1, half_width, half_height ));
        rects.push(Rect::new( rect.x1, rect.y1 + half_height, half_width, half_height ));
        rects.push(Rect::new( rect.x1 + half_width, rect.y1, half_width, half_height ));
        rects.push(Rect::new( rect.x1 + half_width, rect.y1 + half_height, half_width, half_height ));

        rects
    }

    fn get_random_rect(&self, rng : &mut StdRng, rects: &[Rect]) -> Rect {
        if rects.len() == 1 { return rects[0]; }
        let idx = rng.random_range(0, rects.len());
        rects[idx]
    }

    fn get_random_sub_rect(&self, rect: Rect, rng: &mut StdRng) -> Rect {
        let mut result = rect;
        let rect_width = rect.width();
        let rect_height = rect.height();

        let w = usize::max(3, rng.random_range(1, usize::min(rect_width as usize, 20))) + 1;
        let h = usize::max(3, rng.random_range(1, usize::min(rect_height as usize, 20))) + 1;

        result.x1 += rng.random_range(0, 6);
        result.y1 += rng.random_range(0, 6);
        result.x2 = result.x1 + w;
        result.y2 = result.y1 + h;

        result
    }

Trait Implementations§

Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more
This method tests for self and other values to be equal, and is used by ==.
This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.