Replace the local implementation of 2d geometry by lowdim

This also forces an update of the rand dependency,
so while we are at it we update all the dependencies.
这个提交包含在:
Juergen Stuber
2023-04-10 00:57:36 +02:00
父节点 baf4df6c56
当前提交 7fe895f041
修改 10 个文件,包含 588 行新增475 行删除

查看文件

@@ -56,8 +56,8 @@ fn main() -> std::io::Result<()> {
.take(y_size)
.collect::<Vec<_>>();
loop {
let x = rng.gen_range(0, x_size);
let y = rng.gen_range(0, y_size);
let x = rng.gen_range(0..x_size);
let y = rng.gen_range(0..y_size);
let c = pick_color(c0, c1, &mut rng);
frame[y][x] = c;

查看文件

@@ -12,11 +12,16 @@ use chrono::Timelike;
use rand::thread_rng;
use rand::Rng;
use lowdim::bb2d;
use lowdim::p2d;
use lowdim::v2d;
use lowdim::Array2d;
use lowdim::BBox2d;
use lowdim::Point2d;
use lowdim::Vec2d;
use lowdim::Vector;
use pixelfoo::color::Color;
use pixelfoo::point2d::p2d;
use pixelfoo::point2d::Point2d;
use pixelfoo::vec2d::v2d;
use pixelfoo::vec2d::Vec2d;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum Square {
@@ -37,17 +42,24 @@ impl Square {
}
}
struct Board(Vec<Vec<Square>>);
#[derive(Clone, Debug)]
struct Board(Array2d<i64, Square>);
impl Board {
fn bbox(&self) -> BBox2d {
self.0.bbox()
}
}
fn send<T: Write>(w: &mut T, board: &Board) -> std::io::Result<()> {
for line in &board.0 {
for square in line {
for y in board.bbox().y_range() {
for x in board.bbox().x_range() {
let square = board.0[p2d(x, y)];
let c = match square {
Square::Unused => Color::black(),
Square::Unknown { prio } => {
if *prio == 0 {
if prio == 0 {
Color::black()
} else if *prio > 0 {
} else if prio > 0 {
Color::lightblue()
} else {
Color::darkyellow()
@@ -71,35 +83,32 @@ enum Orientation {
}
impl Board {
fn new(board_size: Vec2d, maze_size: Vec2d) -> Board {
Board(
(0..board_size.y)
.map(move |y| {
(0..board_size.x)
.map(|x| {
if x < maze_size.x && y < maze_size.y {
if x == 0 || x == maze_size.x - 1 || y == 0 || y == maze_size.y - 1
{
Square::Wall
} else if x % 2 != 0 && y % 2 != 0 {
Square::Corridor
} else {
Square::Unknown { prio: 0 }
}
} else {
Square::Unused
}
})
.collect::<Vec<_>>()
})
.collect::<Vec<_>>(),
)
fn new(board_bbox: BBox2d, maze_bbox: BBox2d) -> Board {
Board(Array2d::with(board_bbox, |p| {
if maze_bbox.contains(&p) {
let x = p.x();
let y = p.y();
if x == maze_bbox.x_min()
|| x == maze_bbox.x_max()
|| y == maze_bbox.y_min()
|| y == maze_bbox.y_max()
{
Square::Wall
} else if x % 2 != 0 && y % 2 != 0 {
Square::Corridor
} else {
Square::Unknown { prio: 0 }
}
} else {
Square::Unused
}
}))
}
fn get(&self, pos: Point2d) -> Square {
self.0[pos.y as usize][pos.x as usize]
self.0[pos]
}
fn set(&mut self, pos: Point2d, sq: Square) {
self.0[pos.y as usize][pos.x as usize] = sq;
self.0[pos] = sq;
}
fn set_orientation(&mut self, desired: Orientation, pos: Point2d) {
@@ -107,14 +116,14 @@ impl Board {
match sq {
Square::Unknown { .. } => {
let prio;
if pos.x % 2 == 0 && pos.y % 2 != 0 {
if pos.x() % 2 == 0 && pos.y() % 2 != 0 {
// horizontal corridor, vertical wall
prio = if desired == Orientation::Vertical {
10
} else {
-10
};
} else if pos.x % 2 != 0 && pos.y % 2 == 0 {
} else if pos.x() % 2 != 0 && pos.y() % 2 == 0 {
// vertical corridor, horizontal wall
prio = if desired == Orientation::Horizontal {
10
@@ -137,28 +146,28 @@ impl Board {
self.set_orientation(Orientation::Vertical, pos);
}
fn draw_horizontal_segment(&mut self, pos: Point2d, size: Vec2d) {
for x in 0..size.x {
let xn = size.x - 1 - x;
for x in 0..size.x() {
let xn = size.x() - 1 - x;
self.set_horizontal(pos + v2d(x, 0));
for y in 1..x.min(xn).min(size.y / 2) + 1 {
for y in 1..x.min(xn).min(size.y() / 2) + 1 {
self.set_horizontal(pos + v2d(x, y));
self.set_horizontal(pos + v2d(x, -y));
}
}
}
fn draw_vertical_segment(&mut self, pos: Point2d, size: Vec2d) {
for y in 0..size.y {
let yn = size.y - 1 - y;
for y in 0..size.y() {
let yn = size.y() - 1 - y;
self.set_vertical(pos + v2d(0, y));
for x in 1..y.min(yn).min(size.x / 2) + 1 {
for x in 1..y.min(yn).min(size.x() / 2) + 1 {
self.set_vertical(pos + v2d(x, y));
self.set_vertical(pos + v2d(-x, y));
}
}
}
fn draw_7_segments(&mut self, pos: Point2d, size: Vec2d, segments: u8) {
let length = size.x;
let width = size.y;
let length = size.x();
let width = size.y();
let delta = length + 1;
let hsize = v2d(length, width);
let vsize = v2d(width, length);
@@ -226,7 +235,7 @@ where
open.push(Move {
from,
dir,
prio: prio * 100 + rng.gen_range(0, 1000),
prio: prio * 100 + rng.gen_range(0..1000),
});
}
}
@@ -237,8 +246,8 @@ fn main() -> std::io::Result<()> {
let args = args().collect::<Vec<_>>();
eprintln!("executing {}", args[0]);
let x_size = args[1].parse::<usize>().unwrap();
let y_size = args[2].parse::<usize>().unwrap();
let x_size = args[1].parse::<i64>().unwrap();
let y_size = args[2].parse::<i64>().unwrap();
let arg = args[3].parse::<isize>().unwrap_or(DEFAULT_ARG);
eprintln!("screen size {}x{}, arg {}", x_size, y_size, arg);
@@ -247,14 +256,11 @@ fn main() -> std::io::Result<()> {
let t_frame = 0.040; // s
let delay = Duration::new(0, (1_000_000_000.0 * t_frame) as u32);
let board_size = v2d(x_size as i32, y_size as i32);
let board_bbox = bb2d(0..x_size, 0..y_size);
// round down to odd size for maze
let maze_size = v2d(
(board_size.x - 1) / 2 * 2 + 1,
(board_size.y - 1) / 2 * 2 + 1,
);
let maze_bbox = bb2d(0..(x_size - 1) / 2 * 2 + 1, 0..(y_size - 1) / 2 * 2 + 1);
let mut board = Board(Vec::new());
let mut board = Board::new(board_bbox, maze_bbox);
let mut open = BinaryHeap::new();
let mut last_drawn_minute = 99;
loop {
@@ -267,7 +273,7 @@ fn main() -> std::io::Result<()> {
if m != last_drawn_minute {
last_drawn_minute = m;
board = Board::new(board_size, maze_size);
board = Board::new(board_bbox, maze_bbox);
// draw time in prios
let segment_size = v2d(11, 5);
@@ -277,23 +283,35 @@ fn main() -> std::io::Result<()> {
board.draw_digit(p2d(59, 7), segment_size, (m % 10) as u8);
// start building walls from the border
for x in (2..(maze_size.x - 2)).step_by(2) {
add_move(&board, &mut open, &mut rng, p2d(x, 0), v2d(0, 1));
for x in (2..(maze_bbox.x_max() - 1)).step_by(2) {
add_move(
&board,
&mut open,
&mut rng,
p2d(x, maze_size.y - 1),
p2d(x, maze_bbox.y_min()),
v2d(0, 1),
);
add_move(
&board,
&mut open,
&mut rng,
p2d(x, maze_bbox.y_max()),
v2d(0, -1),
);
}
for y in (2..(maze_size.y - 2)).step_by(2) {
add_move(&board, &mut open, &mut rng, p2d(0, y), v2d(1, 0));
for y in (2..(maze_bbox.y_max() - 1)).step_by(2) {
add_move(
&board,
&mut open,
&mut rng,
p2d(maze_size.x - 1, y),
p2d(maze_bbox.x_min(), y),
v2d(1, 0),
);
add_move(
&board,
&mut open,
&mut rng,
p2d(maze_bbox.x_max(), y),
v2d(-1, 0),
);
}
@@ -316,7 +334,7 @@ fn main() -> std::io::Result<()> {
board.set(p1, Square::Wall);
board.set(p2, Square::Wall);
for dir1 in Vec2d::directions() {
for dir1 in Vec2d::unit_vecs_l1() {
let p3 = p2 + dir1;
let p4 = p3 + dir1;
if board.get(p3).is_unknown() {
@@ -332,12 +350,12 @@ fn main() -> std::io::Result<()> {
}
if open.is_empty() {
board.set(p2d(1, 1), Square::Start);
board.set(p2d(maze_size.x - 2, maze_size.y - 2), Square::Finish);
board.set(maze_bbox.min() + v2d(1, 1), Square::Start);
board.set(maze_bbox.max() - v2d(1, 1), Square::Finish);
}
}
let mut buf = Vec::with_capacity((board_size.x * board_size.y * 3) as usize);
let mut buf = Vec::with_capacity(board_bbox.area() * 3);
send(&mut buf, &board)?;
stdout().write_all(&buf)?;
stdout().flush()?;

查看文件

@@ -12,11 +12,16 @@ use chrono::Timelike;
use rand::thread_rng;
use rand::Rng;
use lowdim::bb2d;
use lowdim::p2d;
use lowdim::v2d;
use lowdim::Array2d;
use lowdim::BBox2d;
use lowdim::Point2d;
use lowdim::Vec2d;
use lowdim::Vector;
use pixelfoo::color::Color;
use pixelfoo::point2d::p2d;
use pixelfoo::point2d::Point2d;
use pixelfoo::vec2d::v2d;
use pixelfoo::vec2d::Vec2d;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum Square {
@@ -37,17 +42,24 @@ impl Square {
}
}
struct Board(Vec<Vec<Square>>);
#[derive(Clone, Debug)]
struct Board(Array2d<i64, Square>);
impl Board {
fn bbox(&self) -> BBox2d {
self.0.bbox()
}
}
fn send<T: Write>(w: &mut T, board: &Board) -> std::io::Result<()> {
for line in &board.0 {
for square in line {
for y in board.bbox().y_range() {
for x in board.bbox().x_range() {
let square = board.0[p2d(x, y)];
let c = match square {
Square::Unused => Color::black(),
Square::Unknown { prio } => {
if *prio == 0 {
if prio == 0 {
Color::black()
} else if *prio < 0 {
} else if prio < 0 {
Color::lightblue()
} else {
Color::darkyellow()
@@ -71,37 +83,31 @@ enum Orientation {
}
impl Board {
fn new(board_size: Vec2d, maze_size: Vec2d) -> Board {
Board(
(0..board_size.y)
.map(move |y| {
(0..board_size.x)
.map(|x| {
if x < maze_size.x && y < maze_size.y {
if x == 0
|| x == maze_size.x - 1
|| y == 0
|| y == maze_size.y - 1
|| (x % 2 == 0 && y % 2 == 0)
{
Square::Wall
} else {
Square::Unknown { prio: 0 }
}
} else {
Square::Unused
}
})
.collect::<Vec<_>>()
})
.collect::<Vec<_>>(),
)
fn new(board_bbox: BBox2d, maze_bbox: BBox2d) -> Board {
Board(Array2d::with(board_bbox, |p| {
if maze_bbox.contains(&p) {
let x = p.x();
let y = p.y();
if x == maze_bbox.x_min()
|| x == maze_bbox.x_max()
|| y == maze_bbox.y_min()
|| y == maze_bbox.y_max()
|| (x % 2 == 0 && y % 2 == 0)
{
Square::Wall
} else {
Square::Unknown { prio: 0 }
}
} else {
Square::Unused
}
}))
}
fn get(&self, pos: Point2d) -> Square {
self.0[pos.y as usize][pos.x as usize]
self.0[pos]
}
fn set(&mut self, pos: Point2d, sq: Square) {
self.0[pos.y as usize][pos.x as usize] = sq;
self.0[pos] = sq;
}
fn set_orientation(&mut self, desired: Orientation, pos: Point2d) {
@@ -109,14 +115,14 @@ impl Board {
match sq {
Square::Unknown { .. } => {
let prio;
if pos.x % 2 == 0 && pos.y % 2 != 0 {
if pos.x() % 2 == 0 && pos.y() % 2 != 0 {
// horizontal corridor, vertical wall
prio = if desired == Orientation::Horizontal {
10
} else {
-10
};
} else if pos.x % 2 != 0 && pos.y % 2 == 0 {
} else if pos.x() % 2 != 0 && pos.y() % 2 == 0 {
// vertical corridor, horizontal wall
prio = if desired == Orientation::Vertical {
10
@@ -139,28 +145,28 @@ impl Board {
self.set_orientation(Orientation::Vertical, pos);
}
fn draw_horizontal_segment(&mut self, pos: Point2d, size: Vec2d) {
for x in 0..size.x {
let xn = size.x - 1 - x;
for x in 0..size.x() {
let xn = size.x() - 1 - x;
self.set_horizontal(pos + v2d(x, 0));
for y in 1..x.min(xn).min(size.y / 2) + 1 {
for y in 1..x.min(xn).min(size.y() / 2) + 1 {
self.set_horizontal(pos + v2d(x, y));
self.set_horizontal(pos + v2d(x, -y));
}
}
}
fn draw_vertical_segment(&mut self, pos: Point2d, size: Vec2d) {
for y in 0..size.y {
let yn = size.y - 1 - y;
for y in 0..size.y() {
let yn = size.y() - 1 - y;
self.set_vertical(pos + v2d(0, y));
for x in 1..y.min(yn).min(size.x / 2) + 1 {
for x in 1..y.min(yn).min(size.x() / 2) + 1 {
self.set_vertical(pos + v2d(x, y));
self.set_vertical(pos + v2d(-x, y));
}
}
}
fn draw_7_segments(&mut self, pos: Point2d, size: Vec2d, segments: u8) {
let length = size.x;
let width = size.y;
let length = size.x();
let width = size.y();
let delta = length + 1;
let hsize = v2d(length, width);
let vsize = v2d(width, length);
@@ -228,7 +234,7 @@ where
open.push(Move {
from,
dir,
prio: prio * 100 + rng.gen_range(0, 1000),
prio: prio * 100 + rng.gen_range(0..1000),
});
}
}
@@ -239,8 +245,8 @@ fn main() -> std::io::Result<()> {
let args = args().collect::<Vec<_>>();
eprintln!("executing {}", args[0]);
let x_size = args[1].parse::<usize>().unwrap();
let y_size = args[2].parse::<usize>().unwrap();
let x_size = args[1].parse::<i64>().unwrap();
let y_size = args[2].parse::<i64>().unwrap();
let arg = args[3].parse::<isize>().unwrap_or(DEFAULT_ARG);
eprintln!("screen size {}x{}, arg {}", x_size, y_size, arg);
@@ -249,16 +255,13 @@ fn main() -> std::io::Result<()> {
let t_frame = 0.040; // s
let delay = Duration::new(0, (1_000_000_000.0 * t_frame) as u32);
let board_size = v2d(x_size as i32, y_size as i32);
let board_bbox = bb2d(0..x_size, 0..y_size);
// round down to odd size for maze
let maze_size = v2d(
(board_size.x - 1) / 2 * 2 + 1,
(board_size.y - 1) / 2 * 2 + 1,
);
let maze_bbox = bb2d(0..(x_size - 1) / 2 * 2 + 1, 0..(y_size - 1) / 2 * 2 + 1);
// pick odd position at or near the middle
let maze_mid = p2d((maze_size.x - 1) / 4 * 2 + 1, (maze_size.y - 1) / 4 * 2 + 1);
let maze_mid = maze_bbox.center();
let mut board = Board(Vec::new());
let mut board = Board::new(board_bbox, maze_bbox);
let mut open = BinaryHeap::new();
let mut last_drawn_minute = 99;
loop {
@@ -271,7 +274,7 @@ fn main() -> std::io::Result<()> {
if m != last_drawn_minute {
last_drawn_minute = m;
board = Board::new(board_size, maze_size);
board = Board::new(board_bbox, maze_bbox);
// draw time in prios
let segment_size = v2d(11, 5);
@@ -305,7 +308,7 @@ fn main() -> std::io::Result<()> {
board.set(p1, Square::Corridor);
board.set(p2, Square::Corridor);
for dir1 in Vec2d::directions() {
for dir1 in Vec2d::unit_vecs_l1() {
let p3 = p2 + dir1;
let p4 = p3 + dir1;
if board.get(p3).is_unknown() {
@@ -321,12 +324,12 @@ fn main() -> std::io::Result<()> {
}
if open.is_empty() {
board.set(p2d(1, 1), Square::Start);
board.set(p2d(maze_size.x - 2, maze_size.y - 2), Square::Finish);
board.set(maze_bbox.min() + v2d(1, 1), Square::Start);
board.set(maze_bbox.max() - v2d(1, 1), Square::Finish);
}
}
let mut buf = Vec::with_capacity((board_size.x * board_size.y * 3) as usize);
let mut buf = Vec::with_capacity(board_bbox.area() * 3);
send(&mut buf, &board)?;
stdout().write_all(&buf)?;
stdout().flush()?;

查看文件

@@ -1,18 +1,19 @@
use std::env::args;
use std::io::stdout;
use std::io::Write;
use std::iter::repeat_with;
use std::thread::sleep;
use std::time::Duration;
use rand::thread_rng;
use rand::Rng;
use lowdim::bb2d;
use lowdim::p2d;
use lowdim::Array2d;
use lowdim::BBox2d;
use lowdim::Point2d;
use pixelfoo::color::Color;
use pixelfoo::point2d::Point2d;
use pixelfoo::rect2d::Rect2d;
use pixelfoo::vec2d::v2d;
use pixelfoo::vec2d::Vec2d;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum Square {
@@ -22,40 +23,27 @@ enum Square {
Fox,
}
struct Board(Vec<Vec<Square>>);
#[derive(Clone, Debug)]
struct Board(Array2d<i64, Square>);
impl Board {
pub fn new(size: Vec2d, mut f: impl FnMut() -> Square) -> Board {
Board(
repeat_with(|| {
repeat_with(&mut f)
.take(size.x as usize)
.collect::<Vec<_>>()
})
.take(size.y as usize)
.collect::<Vec<_>>(),
)
pub fn new(bbox: BBox2d, mut f: impl FnMut() -> Square) -> Board {
Board(Array2d::with(bbox, |_p| f()))
}
pub fn size(&self) -> Vec2d {
let x_size = self.0[0].len() as i32;
let y_size = self.0.len() as i32;
v2d(x_size, y_size)
fn bbox(&self) -> BBox2d {
self.0.bbox()
}
pub fn rect(&self) -> Rect2d {
Rect2d::new(0, self.size().x, 0, self.size().y)
fn get(&self, pos: Point2d) -> Square {
self.0[pos]
}
pub fn get(&self, pos: Point2d) -> Square {
self.0[pos.y as usize][pos.x as usize]
}
pub fn set(&mut self, pos: Point2d, sq: Square) {
self.0[pos.y as usize][pos.x as usize] = sq;
fn set(&mut self, pos: Point2d, sq: Square) {
self.0[pos] = sq;
}
}
fn send<T: Write>(w: &mut T, board: &Board) -> std::io::Result<()> {
let Board(lines) = board;
for line in lines {
for square in line {
for y in board.bbox().y_range() {
for x in board.bbox().x_range() {
let square = board.0[p2d(x, y)];
let c = match square {
Square::Empty => Color::blue(),
Square::Grass => Color::green(),
@@ -68,11 +56,9 @@ fn send<T: Write>(w: &mut T, board: &Board) -> std::io::Result<()> {
w.flush()
}
const DEFAULT_ARG: usize = 10;
fn grow(board: &Board, pos: Point2d, grow: Square, die: Square) -> Square {
for pos1 in pos.neighbours() {
if board.rect().contains(pos1) {
for pos1 in pos.neighbors_l1() {
if board.bbox().contains(&pos1) {
let neigh_sq = board.get(pos1);
if neigh_sq == grow {
return grow;
@@ -82,23 +68,24 @@ fn grow(board: &Board, pos: Point2d, grow: Square, die: Square) -> Square {
die
}
const DEFAULT_ARG: usize = 10;
fn main() -> std::io::Result<()> {
let args = args().collect::<Vec<_>>();
eprintln!("executing {}", args[0]);
let x_size = args[1].parse::<usize>().unwrap();
let y_size = args[2].parse::<usize>().unwrap();
let x_size = args[1].parse::<i64>().unwrap();
let y_size = args[2].parse::<i64>().unwrap();
let arg = args[3].parse::<usize>().unwrap_or(DEFAULT_ARG);
eprintln!("screen size {}x{}, arg {}", x_size, y_size, arg);
let mut rng = thread_rng();
let size = v2d(x_size as i32, y_size as i32);
let bbox = bb2d(0..x_size, 0..y_size);
let p_empty = 0.25;
let p_grass = 0.25;
let p_rabbit = 0.25;
// p_fox = 0.05
let mut board = Board::new(size, || {
let mut board = Board::new(bbox, || {
let p = rng.gen::<f64>();
if p < p_empty {
Square::Empty
@@ -115,18 +102,18 @@ fn main() -> std::io::Result<()> {
let delay = Duration::new(0, (1_000_000_000.0 * t_frame) as u32);
// mid point of the board
let x_mid = (x_size - 1) as f64 / 2.0;
let y_mid = (y_size - 1) as f64 / 2.0;
let x_mid = (bbox.x_min() + bbox.x_max()) as f64 / 2.0;
let y_mid = (bbox.y_min() + bbox.y_max()) as f64 / 2.0;
// radius of the death zone in the middle
let r = (x_size.min(y_size) - 1) as f64 / 2.5;
loop {
for _ in 0..arg {
let pos = board.rect().random_point(&mut rng);
let pos = bbox.random_point(&mut rng);
let sq = board.get(pos);
let dx = (pos.x as f64 - x_mid as f64) / r as f64;
let dy = (pos.y as f64 - y_mid as f64) / r as f64;
let dx = (pos.x() as f64 - x_mid as f64) / r as f64;
let dy = (pos.y() as f64 - y_mid as f64) / r as f64;
let p0 = (dx * dx + dy * dy).min(1.0);
let p_survive = match sq {
Square::Empty => 1.0,
@@ -150,7 +137,7 @@ fn main() -> std::io::Result<()> {
);
}
let mut buf = Vec::with_capacity(x_size * y_size * 3);
let mut buf = Vec::with_capacity(bbox.area() * 3);
send(&mut buf, &board)?;
stdout().write_all(&buf)?;
stdout().flush()?;

查看文件

@@ -1,7 +1 @@
pub mod color;
pub mod vec2d;
pub mod point2d;
pub mod rect2d;

查看文件

@@ -1,63 +0,0 @@
use std::ops::Add;
use crate::vec2d::Vec2d;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Point2d {
pub x: i32,
pub y: i32,
}
impl Point2d {
pub fn new(x: i32, y: i32) -> Point2d {
Point2d { x, y }
}
pub fn neighbours(&self) -> Vec<Point2d> {
Vec2d::directions().iter().map(|v| self + v).collect()
}
}
pub fn p2d(x: i32, y: i32) -> Point2d {
Point2d::new(x, y)
}
impl Add<Vec2d> for Point2d {
type Output = Point2d;
fn add(self, other: Vec2d) -> Point2d {
let x = self.x + other.x;
let y = self.y + other.y;
Point2d { x, y }
}
}
impl<'a> Add<&'a Vec2d> for Point2d {
type Output = Point2d;
fn add(self, other: &'a Vec2d) -> Point2d {
let x = self.x + other.x;
let y = self.y + other.y;
Point2d { x, y }
}
}
impl<'a> Add<Vec2d> for &'a Point2d {
type Output = Point2d;
fn add(self, other: Vec2d) -> Point2d {
let x = self.x + other.x;
let y = self.y + other.y;
Point2d { x, y }
}
}
impl<'a> Add<&'a Vec2d> for &'a Point2d {
type Output = Point2d;
fn add(self, other: &'a Vec2d) -> Point2d {
let x = self.x + other.x;
let y = self.y + other.y;
Point2d { x, y }
}
}

查看文件

@@ -1,58 +0,0 @@
use rand::Rng;
use crate::point2d::p2d;
use crate::point2d::Point2d;
use crate::vec2d::v2d;
use crate::vec2d::Vec2d;
pub struct Rect2d {
origin: Point2d,
size: Vec2d,
}
impl Rect2d {
pub fn new(x0: i32, x1: i32, y0: i32, y1: i32) -> Rect2d {
assert!(x0 <= x1 && y0 <= y1);
let origin = p2d(x0, y0);
let size = v2d(x1 - x0, y1 - y0);
Rect2d { origin, size }
}
pub fn left(&self) -> i32 {
self.origin.x
}
pub fn right(&self) -> i32 {
self.origin.x + self.size.x
}
pub fn bottom(&self) -> i32 {
self.origin.y
}
pub fn top(&self) -> i32 {
self.origin.y + self.size.y
}
pub fn width(&self) -> i32 {
self.size.x
}
pub fn height(&self) -> i32 {
self.size.y
}
pub fn contains(&self, p: Point2d) -> bool {
self.left() <= p.x && p.x < self.right() && self.bottom() <= p.y && p.y < self.top()
}
pub fn random_point<R>(&self, rng: &mut R) -> Point2d
where
R: Rng,
{
let x = rng.gen_range(self.left(), self.right());
let y = rng.gen_range(self.bottom(), self.top());
p2d(x, y)
}
}
pub fn r2d(x0: i32, x1: i32, y0: i32, y1: i32) -> Rect2d {
Rect2d::new(x0, x1, y0, y1)
}

查看文件

@@ -1,61 +0,0 @@
use std::ops::Add;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Vec2d {
pub x: i32,
pub y: i32,
}
impl Vec2d {
pub fn new(x: i32, y: i32) -> Vec2d {
Vec2d { x, y }
}
pub fn directions() -> Vec<Vec2d> {
vec![v2d(1, 0), v2d(0, 1), v2d(-1, 0), v2d(0, -1)]
}
}
pub fn v2d(x: i32, y: i32) -> Vec2d {
Vec2d::new(x, y)
}
impl Add for Vec2d {
type Output = Vec2d;
fn add(self, other: Vec2d) -> Vec2d {
let x = self.x + other.x;
let y = self.y + other.y;
Vec2d { x, y }
}
}
impl<'a> Add<&'a Vec2d> for Vec2d {
type Output = Vec2d;
fn add(self, other: &'a Vec2d) -> Vec2d {
let x = self.x + other.x;
let y = self.y + other.y;
Vec2d { x, y }
}
}
impl<'a> Add<Vec2d> for &'a Vec2d {
type Output = Vec2d;
fn add(self, other: Vec2d) -> Vec2d {
let x = self.x + other.x;
let y = self.y + other.y;
Vec2d { x, y }
}
}
impl<'a> Add<&'a Vec2d> for &'a Vec2d {
type Output = Vec2d;
fn add(self, other: &'a Vec2d) -> Vec2d {
let x = self.x + other.x;
let y = self.y + other.y;
Vec2d { x, y }
}
}