Struct mapgen::geometry::Point

source ·
pub struct Point {
    pub x: usize,
    pub y: usize,
}
Expand description

Position on the map

Fields§

§x: usize§y: usize

Implementations§

Create new point

Examples found in repository?
src/geometry.rs (line 19)
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
    pub fn new_i32(x: i32, y: i32) -> Point {
        Point::new(x as usize, y as usize)
    }

    /// Euclidean distance to a given point
    pub fn distance_to(self, point: &Point) -> f32 {
        let a = (self.x as f32 - point.x as f32).powf(2.0);
        let b = (self.y as f32 - point.y as f32).powf(2.0);
        (a + b).sqrt()
    }
}

/// Rectangle region on the map
#[derive(PartialEq, Copy, Clone, Debug)]
pub struct Rect {
    pub x1 : usize,
    pub x2 : usize,
    pub y1 : usize,
    pub y2 : usize
}

impl Rect {
    pub fn new(x: usize, y: usize, width: usize, height: usize) -> Rect {
        Rect{x1:x, y1:y, x2:x+width, y2:y+height}
    }

    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)
    }

    /// Returns true if this overlaps with other
    pub fn intersect(&self, other:&Rect) -> bool {
        self.x1 <= other.x2 && self.x2 >= other.x1 && self.y1 <= other.y2 && self.y2 >= other.y1
    }

    pub fn center(&self) -> Point {
        Point::new((self.x1 + self.x2)/2, (self.y1 + self.y2)/2)
    }
More examples
Hide additional examples
src/filter/distant_exit.rs (line 44)
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
    fn build(&self, map: &MapBuffer) -> MapBuffer {
        let mut new_map = map.clone();

        let mut best_idx = 0;
        let mut best_value = 0.0;
        let dijkstra_map = DijkstraMap::new(map);
        for (i, &value) in dijkstra_map.tiles.iter().enumerate() {
            if value < f32::MAX && value > best_value {
                best_value = value;
                best_idx = i;
            } 
        }
        let x = best_idx % map.width;
        let y = best_idx / map.width;
        new_map.exit_point = Some(Point::new(x, y));
        new_map
    }
src/map_buffer.rs (line 169)
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
    pub fn add_corridor(&mut self, from: Point, to:Point) {
        let mut corridor = Vec::new();
        let mut x = from.x;
        let mut y = from.y;

        while x != to.x || y != to.y {
            if x < to.x {
                x += 1;
            } else if x > to.x {
                x -= 1;
            } else if y < to.y {
                y += 1;
            } else if y > to.y {
                y -= 1;
            }

            if self.is_blocked(x, y) {
                corridor.push(Point::new(x, y));
                self.set_walkable(x, y, true);
            }
        }
    }
src/filter/bsp_interior.rs (line 69)
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
    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 
    }
src/filter/starting_point.rs (line 74)
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
    fn build(&self, map : &MapBuffer) -> MapBuffer {
        let seed_x = match self.x {
            XStart::LEFT => 1,
            XStart::CENTER => map.width / 2,
            XStart::RIGHT => map.width - 2
        };

        let seed_y = match self.y {
            YStart::TOP => 1,
            YStart::CENTER => map.height / 2,
            YStart::BOTTOM => map.height - 2
        };

        let mut available_floors : Vec<(usize, f32)> = Vec::new();
        for (idx, &w) in map.walkables.iter().enumerate() {
            if w {
                available_floors.push(
                    (
                        idx,
                        Point::new(idx % map.width, idx / map.width)
                            .distance_to(&Point::new(seed_x, seed_y))
                    )
                );
            }
        }
        if available_floors.is_empty() {
            panic!("No valid floors to start on");
        }

        available_floors.sort_by(|a,b| a.1.partial_cmp(&b.1).unwrap());

        let start_x = available_floors[0].0 % map.width;
        let start_y = available_floors[0].0 / map.width;

        let mut new_map = map.clone();
        new_map.starting_point = Some(Point::new(start_x, start_y));
        new_map
    }
src/filter/voronoi.rs (line 54)
43
44
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
    fn build(&self, rng: &mut StdRng, map: &MapBuffer) -> MapBuffer {
        let mut new_map = map.clone();
        let seeds = self.generate_seeds(rng, map.width, map.height);

        let mut voronoi_distance = vec![(0, 0.0f32) ; self.n_seeds];
        let mut voronoi_membership : Vec<i32> = vec![0 ; map.width as usize * map.height as usize];
        for (i, vid) in voronoi_membership.iter_mut().enumerate() {
            let x = i % map.width;
            let y = i / map.width;

            for (seed, pos) in seeds.iter().enumerate() {
                let distance = pos.distance_to(&Point::new(x, y));
                voronoi_distance[seed] = (seed, distance);
            }

            voronoi_distance.sort_by(|a,b| a.1.partial_cmp(&b.1).unwrap());

            *vid = voronoi_distance[0].0 as i32;
        }

        for y in 1..new_map.height-1 {
            for x in 1..new_map.width-1 {
                let mut neighbors = 0;
                let my_idx = new_map.xy_idx(x, y);
                let my_seed = voronoi_membership[my_idx];
                if voronoi_membership[new_map.xy_idx(x-1, y)] != my_seed { neighbors += 1; }
                if voronoi_membership[new_map.xy_idx(x+1, y)] != my_seed { neighbors += 1; }
                if voronoi_membership[new_map.xy_idx(x, y-1)] != my_seed { neighbors += 1; }
                if voronoi_membership[new_map.xy_idx(x, y+1)] != my_seed { neighbors += 1; }

                if neighbors < 2 {
                    new_map.set_walkable(x, y, true);
                }
            }
        }

        new_map
    }    
    
    /// Generate random seeds
    fn generate_seeds(&self, rng: &mut StdRng, width: usize, height: usize) -> Vec<Point> {
        let mut seeds: Vec<Point> = Vec::new();

        while seeds.len() < self.n_seeds {
            let vx = rng.roll_dice(1, width-1);
            let vy = rng.roll_dice(1, height-1);
            let candidate = Point::new(vx, vy);
            if !seeds.contains(&candidate) {
                seeds.push(candidate);
            }
        }

        seeds
    }

Create new point from i32 coords

Euclidean distance to a given point

Examples found in repository?
src/filter/rooms_corridors_nearest.rs (line 33)
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
    }
More examples
Hide additional examples
src/filter/starting_point.rs (line 75)
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
    fn build(&self, map : &MapBuffer) -> MapBuffer {
        let seed_x = match self.x {
            XStart::LEFT => 1,
            XStart::CENTER => map.width / 2,
            XStart::RIGHT => map.width - 2
        };

        let seed_y = match self.y {
            YStart::TOP => 1,
            YStart::CENTER => map.height / 2,
            YStart::BOTTOM => map.height - 2
        };

        let mut available_floors : Vec<(usize, f32)> = Vec::new();
        for (idx, &w) in map.walkables.iter().enumerate() {
            if w {
                available_floors.push(
                    (
                        idx,
                        Point::new(idx % map.width, idx / map.width)
                            .distance_to(&Point::new(seed_x, seed_y))
                    )
                );
            }
        }
        if available_floors.is_empty() {
            panic!("No valid floors to start on");
        }

        available_floors.sort_by(|a,b| a.1.partial_cmp(&b.1).unwrap());

        let start_x = available_floors[0].0 % map.width;
        let start_y = available_floors[0].0 / map.width;

        let mut new_map = map.clone();
        new_map.starting_point = Some(Point::new(start_x, start_y));
        new_map
    }
src/filter/voronoi.rs (line 54)
43
44
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(&self, rng: &mut StdRng, map: &MapBuffer) -> MapBuffer {
        let mut new_map = map.clone();
        let seeds = self.generate_seeds(rng, map.width, map.height);

        let mut voronoi_distance = vec![(0, 0.0f32) ; self.n_seeds];
        let mut voronoi_membership : Vec<i32> = vec![0 ; map.width as usize * map.height as usize];
        for (i, vid) in voronoi_membership.iter_mut().enumerate() {
            let x = i % map.width;
            let y = i / map.width;

            for (seed, pos) in seeds.iter().enumerate() {
                let distance = pos.distance_to(&Point::new(x, y));
                voronoi_distance[seed] = (seed, distance);
            }

            voronoi_distance.sort_by(|a,b| a.1.partial_cmp(&b.1).unwrap());

            *vid = voronoi_distance[0].0 as i32;
        }

        for y in 1..new_map.height-1 {
            for x in 1..new_map.width-1 {
                let mut neighbors = 0;
                let my_idx = new_map.xy_idx(x, y);
                let my_seed = voronoi_membership[my_idx];
                if voronoi_membership[new_map.xy_idx(x-1, y)] != my_seed { neighbors += 1; }
                if voronoi_membership[new_map.xy_idx(x+1, y)] != my_seed { neighbors += 1; }
                if voronoi_membership[new_map.xy_idx(x, y-1)] != my_seed { neighbors += 1; }
                if voronoi_membership[new_map.xy_idx(x, y+1)] != my_seed { neighbors += 1; }

                if neighbors < 2 {
                    new_map.set_walkable(x, y, true);
                }
            }
        }

        new_map
    }

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
Returns the “default value” for a type. Read more
Feeds this value into the given Hasher. Read more
Feeds a slice of this type into the given Hasher. 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.