Skip to content

Commit bd041f2

Browse files
committed
square mode
1 parent a2dc866 commit bd041f2

File tree

3 files changed

+159
-55
lines changed

3 files changed

+159
-55
lines changed

jigsaw_puzzle_generator/examples/generator.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@ fn main() {
99
}
1010
let env = Env::default();
1111
Builder::from_env(env).format_timestamp_millis().init();
12-
let image_path = env::args().nth(1).unwrap_or("raw.jpg".to_string());
13-
let template = JigsawGenerator::from_path(&image_path, 9, 6)
12+
let image_path = env::args()
13+
.nth(1)
14+
.unwrap_or("assets/images/raw.jpg".to_string());
15+
let template = JigsawGenerator::from_path(&image_path, 4, 5)
1416
.expect("Failed to load image")
15-
.generate(GameMode::Classic, false)
17+
.generate(GameMode::Square, false)
1618
.expect("Failed to generate puzzle");
19+
1720
create_dir_all("images").expect("Failed to create images directory");
1821
template
1922
.origin_image

jigsaw_puzzle_generator/src/lib.rs

Lines changed: 145 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,146 @@ impl JigsawGenerator {
654654
let pieces_in_row = self.pieces_in_row;
655655
let (starting_points_x, piece_width) = divide_axis(image_width, pieces_in_column);
656656
let (starting_points_y, piece_height) = divide_axis(image_height, pieces_in_row);
657+
658+
let (vertical_edges, horizontal_edges) = match _game_mode {
659+
GameMode::Classic => self.classic_generator(
660+
image_width,
661+
image_height,
662+
&starting_points_x,
663+
piece_width,
664+
&starting_points_y,
665+
piece_height,
666+
),
667+
GameMode::Square => self.square_generator(
668+
image_width,
669+
image_height,
670+
&starting_points_x,
671+
piece_width,
672+
&starting_points_y,
673+
piece_height,
674+
),
675+
};
676+
677+
let mut pieces = vec![];
678+
let mut i = 0;
679+
for y in starting_points_y.iter() {
680+
for x in starting_points_x.iter() {
681+
debug!("starting process piece {i}");
682+
let (top_index, right_index, bottom_index, left_index) =
683+
get_border_indices(i, pieces_in_column);
684+
let piece = JigsawPiece::new(
685+
i,
686+
(*x, *y),
687+
target_image.dimensions(),
688+
(piece_width, piece_height),
689+
horizontal_edges[top_index].clone(),
690+
vertical_edges[right_index].clone(),
691+
horizontal_edges[bottom_index].clone(),
692+
vertical_edges[left_index].clone(),
693+
)?;
694+
695+
// draw debug line
696+
// piece.draw_debug_line(&mut scaled_image);
697+
698+
pieces.push(piece);
699+
i += 1;
700+
}
701+
}
702+
703+
Ok(JigsawTemplate {
704+
pieces,
705+
origin_image: target_image,
706+
piece_dimensions: (piece_width, piece_height),
707+
number_of_pieces: (pieces_in_column, pieces_in_row),
708+
})
709+
}
710+
711+
fn square_generator(
712+
&self,
713+
image_width: f32,
714+
image_height: f32,
715+
starting_points_x: &Vec<f32>,
716+
_piece_width: f32,
717+
starting_points_y: &Vec<f32>,
718+
_piece_height: f32,
719+
) -> (Vec<Edge>, Vec<Edge>) {
720+
let mut vertical_edges = vec![];
721+
let mut horizontal_edges = vec![];
722+
let mut top_border = true;
723+
for index_y in 0..starting_points_y.len() {
724+
let mut left_border = true;
725+
for index_x in 0..starting_points_x.len() {
726+
horizontal_edges.push(if top_border {
727+
Edge::StraightEdge(StraightEdge {
728+
starting_point: (starting_points_x[index_x], 0.0),
729+
end_point: (end_point_pos(index_x, &starting_points_x, image_width), 0.0),
730+
})
731+
} else {
732+
Edge::StraightEdge(StraightEdge {
733+
starting_point: (starting_points_x[index_x], starting_points_y[index_y]),
734+
end_point: (
735+
end_point_pos(index_x, &starting_points_x, image_width),
736+
starting_points_y[index_y],
737+
),
738+
})
739+
});
740+
741+
vertical_edges.push(if left_border {
742+
Edge::StraightEdge(StraightEdge {
743+
starting_point: (0.0, starting_points_y[index_y]),
744+
end_point: (
745+
0.0,
746+
end_point_pos(index_y, &starting_points_y, image_height),
747+
),
748+
})
749+
} else {
750+
Edge::StraightEdge(StraightEdge {
751+
starting_point: (starting_points_x[index_x], starting_points_y[index_y]),
752+
end_point: (
753+
starting_points_x[index_x],
754+
end_point_pos(index_y, &starting_points_y, image_height),
755+
),
756+
})
757+
});
758+
759+
left_border = false;
760+
}
761+
762+
top_border = false;
763+
764+
// Draw right outer edge
765+
vertical_edges.push(Edge::StraightEdge(StraightEdge {
766+
starting_point: (image_width, starting_points_y[index_y]),
767+
end_point: (
768+
image_width,
769+
end_point_pos(index_y, &starting_points_y, image_height),
770+
),
771+
}));
772+
}
773+
774+
// Draw bottom outer edges
775+
for index_x in 0..starting_points_x.len() {
776+
horizontal_edges.push(Edge::StraightEdge(StraightEdge {
777+
starting_point: (starting_points_x[index_x], image_height),
778+
end_point: (
779+
end_point_pos(index_x, &starting_points_x, image_width),
780+
image_height,
781+
),
782+
}))
783+
}
784+
785+
(vertical_edges, horizontal_edges)
786+
}
787+
788+
fn classic_generator(
789+
&self,
790+
image_width: f32,
791+
image_height: f32,
792+
starting_points_x: &Vec<f32>,
793+
piece_width: f32,
794+
starting_points_y: &Vec<f32>,
795+
piece_height: f32,
796+
) -> (Vec<Edge>, Vec<Edge>) {
657797
let mut contour_gen = EdgeContourGenerator::new(
658798
piece_width,
659799
piece_height,
@@ -723,41 +863,7 @@ impl JigsawGenerator {
723863
),
724864
}))
725865
}
726-
727-
let mut pieces = vec![];
728-
let mut i = 0;
729-
for y in starting_points_y.iter() {
730-
for x in starting_points_x.iter() {
731-
debug!("starting process piece {i}");
732-
let (top_index, right_index, bottom_index, left_index) =
733-
get_border_indices(i, pieces_in_column);
734-
let piece = JigsawPiece::new(
735-
i,
736-
(*x, *y),
737-
target_image.dimensions(),
738-
(piece_width, piece_height),
739-
horizontal_edges[top_index].clone(),
740-
vertical_edges[right_index].clone(),
741-
horizontal_edges[bottom_index].clone(),
742-
vertical_edges[left_index].clone(),
743-
)?;
744-
745-
debug!("calc beziers end {}", i);
746-
747-
// draw debug line
748-
// piece.draw_debug_line(&mut scaled_image);
749-
750-
pieces.push(piece);
751-
i += 1;
752-
}
753-
}
754-
755-
Ok(JigsawTemplate {
756-
pieces,
757-
origin_image: target_image,
758-
piece_dimensions: (piece_width, piece_height),
759-
number_of_pieces: (pieces_in_column, pieces_in_row),
760-
})
866+
(vertical_edges, horizontal_edges)
761867
}
762868
}
763869

@@ -847,14 +953,10 @@ impl JigsawPiece {
847953

848954
let (image_width, image_height) = (origin_image_size.0, origin_image_size.1);
849955
let (piece_width, piece_height) = (piece_size.0, piece_size.1);
850-
let piece_width_offset = piece_width * 0.01;
851-
let piece_height_offset = piece_height * 0.01;
852-
let top_left_x = (box_min.x as f32 - piece_width_offset).max(0.0) as u32;
853-
let top_left_y = (box_min.y as f32 - piece_height_offset).max(0.0) as u32;
854-
let mut crop_width = (box_max.x as f32 - box_min.x as f32 + 2.0 * piece_width_offset)
855-
.max(piece_width) as u32;
856-
let mut crop_height = (box_max.y as f32 - box_min.y as f32 + 2.0 * piece_height_offset)
857-
.max(piece_height) as u32;
956+
let top_left_x = (box_min.x as f32).max(0.0) as u32;
957+
let top_left_y = (box_min.y as f32).max(0.0) as u32;
958+
let mut crop_width = (box_max.x as f32 - box_min.x as f32).max(piece_width) as u32;
959+
let mut crop_height = (box_max.y as f32 - box_min.y as f32).max(piece_height) as u32;
858960
if top_left_x + crop_width > image_width {
859961
crop_width = image_width - top_left_x;
860962
}

src/gameplay.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use bevy::utils::HashSet;
1212
use bevy::window::WindowMode;
1313
use flume::{bounded, Receiver};
1414
use jigsaw_puzzle_generator::image::GenericImageView;
15-
use jigsaw_puzzle_generator::{GameMode, JigsawGenerator, JigsawPiece, JigsawTemplate};
15+
use jigsaw_puzzle_generator::{JigsawGenerator, JigsawPiece, JigsawTemplate};
1616
use log::debug;
1717
use rand::Rng;
1818
use std::ops::DerefMut;
@@ -119,11 +119,7 @@ fn setup_finish_ui(
119119

120120
p.spawn((Text::new("Finish"), TextColor(Color::BLACK), text_font));
121121
p.spawn((
122-
Text::new(format!(
123-
"{} pieces {}",
124-
select_piece.to_string(),
125-
select_game_mode.to_string()
126-
)),
122+
Text::new(format!("{} pieces {}", *select_piece, *select_game_mode)),
127123
TextColor(Color::BLACK),
128124
Node {
129125
margin: UiRect::all(Val::Px(5.0)),
@@ -252,7 +248,6 @@ fn setup_generator(
252248
mut commands: Commands,
253249
images: Res<Assets<Image>>,
254250
origin_image: Res<OriginImage>,
255-
select_game_mode: Res<SelectGameMode>,
256251
select_piece: Res<SelectPiece>,
257252
) {
258253
let image = images.get(&origin_image.0).unwrap();
@@ -301,10 +296,14 @@ struct WhiteImage;
301296
struct ColorImage;
302297

303298
/// Spawn the pieces of the jigsaw puzzle
304-
fn spawn_piece(mut commands: Commands, generator: Res<JigsawPuzzleGenerator>) {
299+
fn spawn_piece(
300+
mut commands: Commands,
301+
generator: Res<JigsawPuzzleGenerator>,
302+
select_game_mode: Res<SelectGameMode>,
303+
) {
305304
debug!("Start to generate pieces");
306305
let start = std::time::Instant::now();
307-
if let Ok(template) = generator.generate(GameMode::Classic, false) {
306+
if let Ok(template) = generator.generate(**select_game_mode, false) {
308307
// commands.insert_resource(JigsawPuzzleTemplate(template.clone()));
309308
let mut wait_crops = vec![];
310309
let (tx, rx) = bounded(template.pieces.len());

0 commit comments

Comments
 (0)