Struct broccoli::container::TreeInd[][src]

#[repr(C)]
pub struct TreeInd<'a, 'b, N: Num, T> { /* fields omitted */ }
Expand description

A less general tree that provides collect functions and also derefs to a Tree.

TreeInd assumes there is a layer of indirection where all the pointers point to the same slice. It uses this assumption to provide collect functions that allow storing query results that can then be iterated through multiple times quickly.

Implementations

Collect all elements based off of a predicate and return a FilteredElements.

Examples

 let mut aabbs = [
    broccoli::bbox(broccoli::rect(0isize, 10, 0, 10), 0),
    broccoli::bbox(broccoli::rect(15, 20, 15, 20), 1),
    broccoli::bbox(broccoli::rect(5, 15, 5, 15), 2),
 ];

 let mut base=broccoli::container::TreeIndBase::new(&mut aabbs,|a|a.rect);
 let mut tree = base.build();

 //Find a group of elements only once.
 let mut pairs=tree.collect_all(|_,b| {
    if b.inner % 2 ==0{
        Some(())
    }else{
        None
    }
 });

 //Iterate over that group multiple times
 for _ in 0..3{
     //mutate every colliding pair.
     for (a,()) in pairs.get_mut(&mut aabbs){
         a.inner+=1;
     }
 }

Find all colliding pairs based on a predicate and return a CollidingPairs.

Examples

 let mut aabbs = [
     broccoli::bbox(broccoli::rect(0isize, 10, 0, 10), 0),
     broccoli::bbox(broccoli::rect(15, 20, 15, 20), 1),
     broccoli::bbox(broccoli::rect(5, 15, 5, 15), 2),
 ];

 let mut base=broccoli::container::TreeIndBase::new(&mut aabbs,|a|a.rect);
 let mut tree = base.build();

 //Find all colliding aabbs only once.
 let mut pairs=tree.collect_colliding_pairs(|a, b| {
    a.inner += 1;
    b.inner += 1;
    Some(())
 });

 //Iterate over the pairs multiple times
 for _ in 0..3{
     //mutate every colliding pair.
     pairs.for_every_pair_mut(&mut aabbs,|a,b,()|{
         a.inner+=1;
         b.inner+=1;
     })
 }

The parallel version of TreeInd::collect_colliding_pairs that instead returns a CollidingPairsPar.

Examples

 use broccoli::par::RayonJoin;
 let mut aabbs = [
     broccoli::bbox(broccoli::rect(0isize, 10, 0, 10), 0),
     broccoli::bbox(broccoli::rect(15, 20, 15, 20), 1),
     broccoli::bbox(broccoli::rect(5, 15, 5, 15), 2),
 ];

 let mut base=broccoli::container::TreeIndBase::new(&mut aabbs,|a|a.rect);
 let mut tree = base.build_par(RayonJoin);

 //Find all colliding aabbs only once.
 let mut pairs=tree.collect_colliding_pairs_par(RayonJoin,|a, b| {
    a.inner += 1;
    b.inner += 1;
    Some(())
 });

 //Iterate over the pairs multiple times
 for _ in 0..3{
     //mutate every colliding pair.
     pairs.for_every_pair_mut_par(RayonJoin,&mut aabbs,|a,b,()|{
         a.inner+=1;
         b.inner+=1;
     })
 }

Methods from Deref<Target = Tree<'b, BBox<N, &'a mut T>>>

Examples

 use broccoli::build;
 const NUM_ELEMENT:usize=40;
 let mut bots = [axgeom::rect(0,10,0,10);NUM_ELEMENT];
 let mut tree = broccoli::new(&mut bots);

 assert_eq!(tree.get_height(),build::TreePreBuilder::new(NUM_ELEMENT).get_height());

Examples

 use broccoli::build;
 let mut bots = [axgeom::rect(0,10,0,10)];
 let mut tree = broccoli::new(&mut bots);

 assert_eq!(tree.num_nodes(),build::TreePreBuilder::new(1).num_nodes());

Examples

 let mut bots = [axgeom::rect(0,10,0,10)];
 let mut tree = broccoli::new(&mut bots);

 assert_eq!(tree.get_nodes()[0].range[0], axgeom::rect(0,10,0,10));

Examples

 let mut bots = [axgeom::rect(0,10,0,10)];
 let mut tree = broccoli::new(&mut bots);

 assert_eq!(tree.get_nodes_mut().get_index_mut(0).range[0], axgeom::rect(0,10,0,10));

Examples

 use broccoli::{bbox,rect};
 let mut bots = [bbox(rect(0,10,0,10),0)];
 let mut tree = broccoli::new(&mut bots);

 use compt::Visitor;
 for b in tree.vistr_mut().dfs_preorder_iter().flat_map(|n|n.into_range().iter_mut()){
    *b.unpack_inner()+=1;    
 }
 assert_eq!(bots[0].inner,1);

Examples

 use broccoli::{bbox,rect};
 let mut bots = [rect(0,10,0,10)];
 let mut tree = broccoli::new(&mut bots);

 use compt::Visitor;
 let mut test = Vec::new();
 for b in tree.vistr().dfs_preorder_iter().flat_map(|n|n.range.iter()){
    test.push(b);
 }
 assert_eq!(test[0],&axgeom::rect(0,10,0,10));

Return the underlying slice of aabbs in the order sorted during tree construction.

Examples

 let mut bots = [axgeom::rect(0,10,0,10)];
 let mut tree = broccoli::new(&mut bots);

 assert_eq!(*tree.get_elements_mut().get_index_mut(0), axgeom::rect(0,10,0,10));

Return the underlying slice of aabbs in the order sorted during tree construction.

Examples

 let mut bots = [axgeom::rect(0,10,0,10)];
 let tree = broccoli::new(&mut bots);

 assert_eq!(tree.get_elements()[0], axgeom::rect(0,10,0,10));

Find all aabb intersections and return a PMut of it.

Examples

 use broccoli::{bbox,rect};
 let mut bots = [bbox(rect(0,10,0,10),0u8),bbox(rect(5,15,5,15),0u8)];
 let mut tree = broccoli::new(&mut bots);
 tree.find_colliding_pairs_mut(|a,b|{
    *a.unpack_inner()+=1;
    *b.unpack_inner()+=1;
 });

 assert_eq!(bots[0].inner,1);
 assert_eq!(bots[1].inner,1);

The parallel version of Tree::find_colliding_pairs_mut.

Examples

 use broccoli::{bbox,rect,par::RayonJoin};
 let mut bots = [bbox(rect(0,10,0,10),0u8),bbox(rect(5,15,5,15),0u8)];
 let mut tree = broccoli::new(&mut bots);
 tree.find_colliding_pairs_mut_par(RayonJoin,|a,b|{
    *a.unpack_inner()+=1;
    *b.unpack_inner()+=1;
 });

 assert_eq!(bots[0].inner,1);
 assert_eq!(bots[1].inner,1);

For analysis, allows the user to query with custom settings

Examples

 use broccoli::{bbox,rect,par::RayonJoin};
 let mut bots = [bbox(rect(0,10,0,10),0u8),bbox(rect(5,15,5,15),0u8)];
 let mut tree = broccoli::new(&mut bots);

 let builder=tree.new_colfind_builder();
 let builder=builder.with_switch_height(4);
 builder.query_par(RayonJoin,|a,b|{
    *a.unpack_inner()+=1;
    *b.unpack_inner()+=1;
 });

 assert_eq!(bots[0].inner,1);
 assert_eq!(bots[1].inner,1);

Examples

use broccoli::{bbox,rect};
use axgeom::Rect;

let dim=rect(0,100,0,100);
let mut bots =[rect(0,10,0,10)];
let tree=broccoli::new(&mut bots);

let mut rects=Vec::new();
tree.draw_divider(
    |axis,node,rect,_|
    {
        if !node.range.is_empty(){    
            rects.push(
                axis.map_val(
                    Rect {x: node.cont.into(),y: rect.y.into()},
                    Rect {x: rect.x.into(),y: node.cont.into()}
                )   
            );
        }
    },
    dim
);

//rects now contains a bunch of rectangles that can be drawn to visualize
//where all the dividers are and how thick they each are.

Find collisions between elements in this tree, with the specified slice of elements.

Examples

 use broccoli::{bbox,rect};
 let mut bots1 = [bbox(rect(0,10,0,10),0u8)];
 let mut bots2 = [bbox(rect(5,15,5,15),0u8)];
 let mut tree = broccoli::new(&mut bots1);

 tree.intersect_with_mut(&mut bots2,|a,b|{
    *a.unpack_inner()+=1;
    *b.unpack_inner()+=2;    
 });

 assert_eq!(bots1[0].inner,1);
 assert_eq!(bots2[0].inner,2);

Find the closest num elements to the specified point. The user provides two functions:

The result is returned as one Vec. The closest elements will appear first. Multiple elements can be returned with the same distance in the event of ties. These groups of elements are seperated by one entry of Option::None. In order to iterate over each group, try using the slice function: arr.split(|a| a.is_none())

Examples

 use broccoli::{bbox,rect};
 use axgeom::vec2;

 let mut inner1=vec2(5,5);
 let mut inner2=vec2(3,3);
 let mut inner3=vec2(7,7);

 let mut bots = [bbox(rect(0,10,0,10),&mut inner1),
               bbox(rect(2,4,2,4),&mut inner2),
               bbox(rect(6,8,6,8),&mut inner3)];

 let mut tree = broccoli::new(&mut bots);

 let mut handler = broccoli::helper::knearest_from_closure(
    &tree,
    (),
    |_, point, a| Some(a.rect.distance_squared_to_point(point).unwrap_or(0)),
    |_, point, a| a.inner.distance_squared_to_point(point),
    |_, point, a| distance_squared(point.x,a),
    |_, point, a| distance_squared(point.y,a),
 );

 let mut res = tree.k_nearest_mut(
       vec2(30, 30),
       2,
       &mut handler
 );

 assert_eq!(res.len(),2);
 assert_eq!(res.total_len(),2);

 let foo:Vec<_>=res.iter().map(|a|*a[0].bot.inner).collect();

 assert_eq!(foo,vec![vec2(7,7),vec2(5,5)]);


 fn distance_squared(a:isize,b:isize)->isize{
     let a=(a-b).abs();
     a*a
 }

Find the elements that are hit by a ray.

The result is returned as a Vec. In the event of a tie, multiple elements can be returned.

Examples

 use broccoli::{bbox,rect};
 use axgeom::{vec2,ray};


 let mut bots = [bbox(rect(0,10,0,10),vec2(5,5)),
                bbox(rect(2,5,2,5),vec2(4,4)),
                bbox(rect(4,10,4,10),vec2(5,5))];

 let mut bots_copy=bots.clone();
 let mut tree = broccoli::new(&mut bots);
 let ray=ray(vec2(5,-5),vec2(1,2));

 let mut handler = broccoli::helper::raycast_from_closure(
    &tree,
    (),
    |_, _, _| None,
    |_, ray, a| ray.cast_to_rect(&a.rect),
    |_, ray, val| ray.cast_to_aaline(axgeom::XAXIS, val),
    |_, ray, val| ray.cast_to_aaline(axgeom::YAXIS, val),
 );
 let res = tree.raycast_mut(
     ray,
     &mut handler);

 let res=res.unwrap();
 assert_eq!(res.mag,2);
 assert_eq!(res.elems.len(),1);
 assert_eq!(res.elems[0].inner,vec2(5,5));

Examples

 use broccoli::{bbox,rect};
 let mut bots = [rect(0,10,0,10),rect(20,30,20,30)];
 let mut tree = broccoli::new(&mut bots);
 let mut test = Vec::new();
 tree.for_all_intersect_rect(&rect(9,20,9,20),|a|{
    test.push(a);
 });

 assert_eq!(test[0],&rect(0,10,0,10));

Examples

 use broccoli::{bbox,rect};
 let mut bots = [bbox(rect(0,10,0,10),0u8)];
 let mut tree = broccoli::new(&mut bots);
 tree.for_all_intersect_rect_mut(&rect(9,20,9,20),|a|{
    *a.unpack_inner()+=1;    
 });

 assert_eq!(bots[0].inner,1);

Examples

 use broccoli::{bbox,rect};
 let mut bots = [rect(0,10,0,10),rect(20,30,20,30)];
 let mut tree = broccoli::new(&mut bots);
 let mut test = Vec::new();
 tree.for_all_in_rect(&rect(0,20,0,20),|a|{
    test.push(a);
 });

 assert_eq!(test[0],&rect(0,10,0,10));

Examples

 use broccoli::{bbox,rect};
 let mut bots = [bbox(rect(0,10,0,10),0u8)];
 let mut tree = broccoli::new(&mut bots);
 tree.for_all_in_rect_mut(&rect(0,10,0,10),|a|{
    *a.unpack_inner()+=1;    
 });

 assert_eq!(bots[0].inner,1);

Examples

 use broccoli::{bbox,rect};
 let mut bots = [bbox(rect(0,10,0,10),0u8)];
 let mut tree = broccoli::new(&mut bots);
 tree.for_all_not_in_rect_mut(&rect(10,20,10,20),|a|{
    *a.unpack_inner()+=1;    
 });

 assert_eq!(bots[0].inner,1);

If we have two non intersecting rectangles, it is safe to return to the user two sets of mutable references of the bots strictly inside each rectangle since it is impossible for a bot to belong to both sets.

Safety

Unsafe code is used. We unsafely convert the references returned by the rect query closure to have a longer lifetime. This allows the user to store mutable references of non intersecting rectangles at the same time. If two requested rectangles intersect, an error is returned.

Handles a multi rect mut “sessions” within which the user can query multiple non intersecting rectangles.

Examples

 use broccoli::{bbox,rect};
 let mut bots1 = [bbox(rect(0,10,0,10),0u8)];
 let mut tree = broccoli::new(&mut bots1);
 let mut multi = tree.multi_rect();

 multi.for_all_in_rect_mut(rect(0,10,0,10),|a|{}).unwrap();
 let res = multi.for_all_in_rect_mut(rect(5,15,5,15),|a|{});
 assert_eq!(res,Err(broccoli::query::RectIntersectErr));

Trait Implementations

The resulting type after dereferencing.

Dereferences the value.

Mutably dereferences the value.

Performs the conversion.

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Performs the conversion.

Performs the conversion.

The alignment of pointer.

The type for initializers.

Initializes a with the given initializer. Read more

Dereferences the given pointer. Read more

Mutably dereferences the given pointer. Read more

Drops the object pointed to by the given pointer. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.