Struct broccoli::Tree[][src]

#[repr(transparent)]
pub struct Tree<'a, T: Aabb> { /* fields omitted */ }
Expand description

A space partitioning tree.

Implementations

Create a Tree.

Examples

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

Create a Tree in parallel.

Examples

 let mut bots = [axgeom::rect(0,10,0,10)];
 let tree = broccoli::Tree::new_par(broccoli::par::RayonJoin,&mut bots);

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;
 const NUM_ELEMENT:usize=7;
 let mut bots = [axgeom::rect(0,10,0,10);NUM_ELEMENT];
 let mut tree = broccoli::new(&mut bots);
 let inner =tree.into_inner();
 assert_eq!(inner.into_nodes().len(),1);

Examples

 use broccoli::build;
 const NUM_ELEMENT:usize=7;
 let mut bots = [axgeom::rect(0,10,0,10);NUM_ELEMENT];
 let mut tree = broccoli::new(&mut bots);
 let inner =tree.into_inner();
 let tree=unsafe{broccoli::Tree::from_raw_parts(inner)};

Safety

Unsafe, since the user may pass in nodes in an arrangement that violates the invariants of the tree.

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 visit every pair wrapped in PMut.

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 find all colliding pairs 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
 }

Perform nbody The tree is taken by value so that its nodes can be expended to include more data.

Perform nbody The tree is taken by value so that its nodes can be expended to include more data.

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

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.