Skip to content

Commit de5dc82

Browse files
fix tile merging
1 parent 94341f2 commit de5dc82

File tree

1 file changed

+83
-17
lines changed

1 file changed

+83
-17
lines changed

node-graph/nodes/vector/src/generator_nodes.rs

Lines changed: 83 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -204,26 +204,92 @@ fn qr_code(
204204

205205
let size = qr_code.size();
206206
let mut vector = Vector::default();
207-
let offset = DVec2::splat(size as f64 / -2.);
208-
209-
for y in 0..size {
210-
let mut x = 0;
211-
while x < size {
212-
if qr_code.get_module(x, y) {
213-
let start_x = x;
214-
x += 1;
215-
if merge {
216-
while x < size && qr_code.get_module(x, y) {
217-
x += 1;
207+
let offset = DVec2::splat(0.0);
208+
209+
if merge {
210+
use std::collections::{HashMap, HashSet, VecDeque};
211+
212+
let mut remaining: HashSet<(i32, i32)> = HashSet::new();
213+
for y in 0..size {
214+
for x in 0..size {
215+
if qr_code.get_module(x, y) {
216+
remaining.insert((x, y));
217+
}
218+
}
219+
}
220+
221+
while let Some(&(start_x, start_y)) = remaining.iter().next() {
222+
let mut island = HashSet::new();
223+
let mut queue = VecDeque::new();
224+
queue.push_back((start_x, start_y));
225+
remaining.remove(&(start_x, start_y));
226+
227+
while let Some((x, y)) = queue.pop_front() {
228+
island.insert((x, y));
229+
for (dx, dy) in [(0, 1), (0, -1), (1, 0), (-1, 0)] {
230+
let nx = x + dx;
231+
let ny = y + dy;
232+
if remaining.remove(&(nx, ny)) {
233+
queue.push_back((nx, ny));
234+
}
235+
}
236+
}
237+
238+
let mut island_edges = HashSet::new();
239+
for &(x, y) in &island {
240+
for (p1, p2) in [((x, y), (x + 1, y)), ((x + 1, y), (x + 1, y + 1)), ((x + 1, y + 1), (x, y + 1)), ((x, y + 1), (x, y))] {
241+
if !island_edges.remove(&(p2, p1)) {
242+
island_edges.insert((p1, p2));
243+
}
244+
}
245+
}
246+
247+
let mut adjacency: HashMap<(i32, i32), Vec<(i32, i32)>> = HashMap::new();
248+
for (p1, p2) in island_edges {
249+
adjacency.entry(p1).or_default().push(p2);
250+
}
251+
252+
while let Some(&start_point) = adjacency.keys().next() {
253+
let mut loop_points = Vec::new();
254+
let mut current = start_point;
255+
256+
loop {
257+
loop_points.push(DVec2::new(current.0 as f64, current.1 as f64));
258+
let next = adjacency.get_mut(&current).and_then(|n| n.pop()).unwrap();
259+
if adjacency.get(&current).map_or(false, |n| n.is_empty()) {
260+
adjacency.remove(&current);
261+
}
262+
current = next;
263+
if current == start_point {
264+
break;
218265
}
219266
}
220-
let end_x = x;
221267

222-
let corner1 = offset + DVec2::new(start_x as f64, y as f64);
223-
let corner2 = offset + DVec2::new(end_x as f64, (y + 1) as f64);
224-
vector.append_subpath(subpath::Subpath::new_rect(corner1, corner2), false);
225-
} else {
226-
x += 1;
268+
if loop_points.len() > 2 {
269+
let mut simplified = Vec::new();
270+
for i in 0..loop_points.len() {
271+
let prev = loop_points[(i + loop_points.len() - 1) % loop_points.len()];
272+
let curr = loop_points[i];
273+
let next = loop_points[(i + 1) % loop_points.len()];
274+
275+
if (curr - prev).perp_dot(next - curr).abs() > 1e-6 {
276+
simplified.push(curr + offset);
277+
}
278+
}
279+
if !simplified.is_empty() {
280+
vector.append_subpath(subpath::Subpath::from_anchors(simplified, true), false);
281+
}
282+
}
283+
}
284+
}
285+
} else {
286+
for y in 0..size {
287+
for x in 0..size {
288+
if qr_code.get_module(x, y) {
289+
let corner1 = offset + DVec2::new(x as f64, y as f64);
290+
let corner2 = corner1 + DVec2::splat(1.);
291+
vector.append_subpath(subpath::Subpath::new_rect(corner1, corner2), false);
292+
}
227293
}
228294
}
229295
}

0 commit comments

Comments
 (0)