conspire/geometry/ntree/balance/quadtree/
mod.rs1use crate::geometry::ntree::{
2 Orthotree,
3 balance::{Balance, Balancing},
4 node::split::Split,
5 pair::Pairing,
6};
7use std::{array::from_fn, ops::Add};
8
9const D: usize = 2;
10const L: usize = 2;
11const M: usize = 4;
12const N: usize = 4;
13
14impl<T, U, V> Balance for Orthotree<D, L, M, N, T, U, V>
15where
16 T: Add<Output = T> + Copy + Split + Into<usize>,
17 U: Copy + From<usize> + Into<usize>,
18 V: Copy,
19{
20 fn balance(&mut self, balancing: Balancing) -> bool {
21 self.balanced = balancing;
22 let mut balanced;
23 let mut balanced_already = true;
24 let mut index;
25 let mut subdivide;
26 let mut vertices = [false; 2];
27 let strong = matches!(balancing, Balancing::Strong);
28 loop {
29 balanced = true;
30 index = 0;
31 subdivide = false;
32 while index < self.len() {
33 if !self[index.into()].is_unit() && self[index.into()].is_leaf() {
34 'faces: for (face, face_cell) in self[index.into()].facets().iter().enumerate()
35 {
36 if let Some(neighbor) = face_cell
37 && let Some(kids) = self[*neighbor].orthants()
38 {
39 if strong {
40 vertices = from_fn(|_| false);
41 }
42 if match face {
43 0 => {
44 if strong {
45 if let Some(vertex_cell) = self[kids[1]].facets()[2] {
46 vertices[0] = self[vertex_cell].is_tree()
47 }
48 if let Some(vertex_cell) = self[kids[3]].facets()[3] {
49 vertices[1] = self[vertex_cell].is_tree()
50 }
51 }
52 self[kids[1]].is_tree()
53 || self[kids[3]].is_tree()
54 || vertices.into_iter().any(|vertex| vertex)
55 }
56 1 => {
57 if strong {
58 if let Some(vertex_cell) = self[kids[0]].facets()[2] {
59 vertices[0] = self[vertex_cell].is_tree()
60 }
61 if let Some(vertex_cell) = self[kids[2]].facets()[3] {
62 vertices[1] = self[vertex_cell].is_tree()
63 }
64 }
65 self[kids[0]].is_tree()
66 || self[kids[2]].is_tree()
67 || vertices.into_iter().any(|vertex| vertex)
68 }
69 2 => self[kids[2]].is_tree() || self[kids[3]].is_tree(),
70 3 => self[kids[0]].is_tree() || self[kids[1]].is_tree(),
71 _ => unreachable!(),
72 } {
73 subdivide = true;
74 break 'faces;
75 }
76 }
77 }
78 if subdivide {
79 self.subdivide(index.into()).unwrap();
80 balanced = false;
81 balanced_already = false;
82 subdivide = false;
83 }
84 }
85 index += 1;
86 }
87 if balanced {
88 break;
89 }
90 }
91 balanced_already
92 }
93 fn pair_up(&mut self, pairing: Pairing) -> Result<bool, &'static str> {
94 self.paired = pairing;
95 self.pair(pairing)
96 }
97}