fn quadratic_partition(
        &self,
        children: Vec<Index>,
    ) -> (Vec<Index>, Vec<Index>, Region, Region) {
        let (ix1, ix2) = self.find_worst_pair(&children);

        let mut unpicked_children: HashSet<usize> = (0..children.len()).collect();
        unpicked_children.remove(&ix1);
        unpicked_children.remove(&ix2);

        // Keep track of nodes in the first group
        let mut group1 = Vec::with_capacity(self.max_children - self.min_children);
        group1.push(ix1);

        // Keep track of the minimum bounding regions for the first and second group
        let mut group1_mbr = self.nodes[children[ix1]].get_region().clone();
        let mut group2_mbr = self.nodes[children[ix2]].get_region().clone();

        // Partition the nodes into two groups.  The basic strategy is that at each stepp
        // we find the unpicked node
        // If one of the groups gets too large, stop.
        while !unpicked_children.is_empty()
            && group1.len() < self.max_children - self.min_children
            && (children.len() - group1.len() - unpicked_children.len())
                < self.max_children - self.min_children
        {
            let mut best_d = std::f64::MAX;
            let mut best_index = None;

            for &index in unpicked_children.iter() {
                let g1r = group1_mbr
                    .combine_region(self.nodes[children[index]].get_region())
                    .expect("failed to combine leaves");
                let g2r = group2_mbr
                    .combine_region(self.nodes[children[index]].get_region())
                    .expect("failed to combine leaves");

                let d1 = g1r.get_area() - group1_mbr.get_area();
                let d2 = g2r.get_area() - group2_mbr.get_area();

                if d1 < d2 && d1 < best_d {
                    best_index = Some((index, 1));
                    best_d = d1;
                } else if d2 < d1 && d2 < best_d {
                    best_index = Some((index, 2));
                    best_d = d2;
                } else if (d1 - d2).abs() < std::f64::EPSILON && d1 < best_d {
                    // in case of ties, assign to MBR with smallest area
                    if group1_mbr.get_area() < group2_mbr.get_area() {
                        best_index = Some((index, 1));
                    } else {
                        best_index = Some((index, 2));
                    }
                    best_d = d1;
                }
            }

            let (best_index, side) = best_index.unwrap();
            unpicked_children.remove(&best_index);

            if side == 1 {
                // add to group 1
                group1.push(best_index);
                group1_mbr.combine_region_in_place(self.nodes[children[best_index]].get_region());
            } else {
                group2_mbr.combine_region_in_place(self.nodes[children[best_index]].get_region());
            }
        }

        if !unpicked_children.is_empty() {
            if group1.len() < self.min_children {
                // rest of the unpicked children go in group 1
                for child_index in unpicked_children {
                    group1_mbr
                        .combine_region_in_place(self.nodes[children[child_index]].get_region());
                    group1.push(child_index);
                }
            } else {
                // rest of the unpicked children go in group 2
                for child_index in unpicked_children {
                    group2_mbr
                        .combine_region_in_place(self.nodes[children[child_index]].get_region());
                }
            }
        }

        let (group1, group2) = Self::assemble(children, group1.into_iter().collect());

        (group1, group2, group1_mbr, group2_mbr)
    }
/// Splits a vector of nodes into two groups using the QuadraticSplit algorithm.
Splits a vector of nodes into two groups using the QuadraticSplit algorithm.
Splits a vector of nodes into two groups using the QuadraticSplit algorithm .
fn quadratic_partition(
        &self,
        children: Vec<Index>,
    ) -> (Vec<Index>, Vec<Index>, Region, Region) {
        let (ix1, ix2) = self.find_worst_pair(&children);
        let mut unpicked_children: HashSet<usize> = (0..children.len()).collect();
        unpicked_children.remove(&ix1);
        unpicked_children.remove(&ix2);
        // Keep track of nodes in the first group
        let mut group1 = Vec::with_capacity(self.max_children - self.min_children);
        group1.push(ix1);
        // Keep track of the minimum bounding regions for the first and second group
        let mut group1_mbr = self.nodes[children[ix1]].get_region().clone();
        let mut group2_mbr = self.nodes[children[ix2]].get_region().clone();
        // Partition the nodes into two groups.  The basic strategy is that at each stepp
        // we find the unpicked node
        // If one of the groups gets too large, stop.
        while !unpicked_children.is_empty()
            && group1.len() < self.max_children - self.min_children
            && (children.len() - group1.len() - unpicked_children.len())
                < self.max_children - self.min_children
        {
            let mut best_d = std::f64::MAX;
            let mut best_index = None;
            for &index in unpicked_children.iter() {
                let g1r = group1_mbr
                    .combine_region(self.nodes[children[index]].get_region())
                    .expect("failed to combine leaves");
                let g2r = group2_mbr
                    .combine_region(self.nodes[children[index]].get_region())
                    .expect("failed to combine leaves");
                let d1 = g1r.get_area() - group1_mbr.get_area();
                let d2 = g2r.get_area() - group2_mbr.get_area();
                if d1 < d2 && d1 < best_d {
                    best_index = Some((index, 1));
                    best_d = d1;
                } else if d2 < d1 && d2 < best_d {
                    best_index = Some((index, 2));
                    best_d = d2;
                } else if (d1 - d2).abs() < std::f64::EPSILON && d1 < best_d {
                    // in case of ties, assign to MBR with smallest area
                    if group1_mbr.get_area() < group2_mbr.get_area() {
                        best_index = Some((index, 1));
                    } else {
                        best_index = Some((index, 2));
                    }
                    best_d = d1;
                }
            }
            let (best_index, side) = best_index.unwrap();
            unpicked_children.remove(&best_index);
            if side == 1 {
                // add to group 1
                group1.push(best_index);
                group1_mbr.combine_region_in_place(self.nodes[children[best_index]].get_region());
            } else {
                group2_mbr.combine_region_in_place(self.nodes[children[best_index]].get_region());
            }
        }
        if !unpicked_children.is_empty() {
            if group1.len() < self.min_children {
                // rest of the unpicked children go in group 1
                for child_index in unpicked_children {
                    group1_mbr
                        .combine_region_in_place(self.nodes[children[child_index]].get_region());
                    group1.push(child_index);
                }
            } else {
                // rest of the unpicked children go in group 2
                for child_index in unpicked_children {
                    group2_mbr
                        .combine_region_in_place(self.nodes[children[child_index]].get_region());
                }
            }
        }
        let (group1, group2) = Self::assemble(children, group1.into_iter().collect());
        (group1, group2, group1_mbr, group2_mbr)
    }
fn quadratic_partition ( & self , children : Vec < Index > , ) -> ( Vec < Index > , Vec < Index > , Region , Region ) { let ( ix1 , ix2 ) = self . find_worst_pair ( & children ) ; let mut unpicked_children : HashSet < usize > = ( 0 .. children . len ( ) ) . collect ( ) ; unpicked_children . remove ( & ix1 ) ; unpicked_children . remove ( & ix2 ) ; // Keep track of nodes in the first group let mut group1 = Vec :: with_capacity ( self . max_children - self . min_children ) ; group1 . push ( ix1 ) ; // Keep track of the minimum bounding regions for the first and second group let mut group1_mbr = self . nodes [ children [ ix1 ] ] . get_region ( ) . clone ( ) ; let mut group2_mbr = self . nodes [ children [ ix2 ] ] . get_region ( ) . clone ( ) ; // Partition the nodes into two groups.  The basic strategy is that at each stepp // we find the unpicked node // If one of the groups gets too large, stop. while ! unpicked_children . is_empty ( ) && group1 . len ( ) < self . max_children - self . min_children && ( children . len ( ) - group1 . len ( ) - unpicked_children . len ( ) ) < self . max_children - self . min_children { let mut best_d = std :: f64 :: MAX ; let mut best_index = None ; for & index in unpicked_children . iter ( ) { let g1r = group1_mbr . combine_region ( self . nodes [ children [ index ] ] . get_region ( ) ) . expect ( " " ) ; let g2r = group2_mbr . combine_region ( self . nodes [ children [ index ] ] . get_region ( ) ) . expect ( " " ) ; let d1 = g1r . get_area ( ) - group1_mbr . get_area ( ) ; let d2 = g2r . get_area ( ) - group2_mbr . get_area ( ) ; if d1 < d2 && d1 < best_d { best_index = Some ( ( index , 1 ) ) ; best_d = d1 ; } else if d2 < d1 && d2 < best_d { best_index = Some ( ( index , 2 ) ) ; best_d = d2 ; } else if ( d1 - d2 ) . abs ( ) < std :: f64 :: EPSILON && d1 < best_d { // in case of ties, assign to MBR with smallest area if group1_mbr . get_area ( ) < group2_mbr . get_area ( ) { best_index = Some ( ( index , 1 ) ) ; } else { best_index = Some ( ( index , 2 ) ) ; } best_d = d1 ; } } let ( best_index , side ) = best_index . unwrap ( ) ; unpicked_children . remove ( & best_index ) ; if side == 1 { // add to group 1 group1 . push ( best_index ) ; group1_mbr . combine_region_in_place ( self . nodes [ children [ best_index ] ] . get_region ( ) ) ; } else { group2_mbr . combine_region_in_place ( self . nodes [ children [ best_index ] ] . get_region ( ) ) ; } } if ! unpicked_children . is_empty ( ) { if group1 . len ( ) < self . min_children { // rest of the unpicked children go in group 1 for child_index in unpicked_children { group1_mbr . combine_region_in_place ( self . nodes [ children [ child_index ] ] . get_region ( ) ) ; group1 . push ( child_index ) ; } } else { // rest of the unpicked children go in group 2 for child_index in unpicked_children { group2_mbr . combine_region_in_place ( self . nodes [ children [ child_index ] ] . get_region ( ) ) ; } } } let ( group1 , group2 ) = Self :: assemble ( children , group1 . into_iter ( ) . collect ( ) ) ; ( group1 , group2 , group1_mbr , group2_mbr ) }
Splits a vector of nodes into two groups using the QuadraticSplit algorithm.
Splits a vector of nodes into two groups using the QuadraticSplit algorithm .
&self
children
Vec<Index>
&self
children
Vec<Index>