1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use rand::*;

mod by_copy;
mod by_borrow;

type T = by_copy::T;

const PRINT_CPP : bool = false;

fn main() {
    let num_shapes = 4000;
    let num_cycles = 5;
    let num_runs = 5;
    let num_warmup = 1;

    let min_pos = 0.0 as T;
    let max_pos = 50.0 as T;
    let min_rad = 0.1 as T;
    let max_rad = 10.0 as T;


    let mut rng = rand::thread_rng();

    let gen_pos1 = |rng: &mut rand::rngs::ThreadRng| -> T { rng.gen_range(min_pos, max_pos) };
    let gen_pos3 = |rng: &mut rand::rngs::ThreadRng| -> (T,T,T) { ( gen_pos1(rng), gen_pos1(rng), gen_pos1(rng) ) };
    let gen_rad = |rng: &mut rand::rngs::ThreadRng| -> T { rng.gen_range(min_rad, max_rad) };

    let mut total_overlap = 0;
    let mut total_copy = 0;
    let mut total_borrow = 0;

    for _ in 0..num_cycles {

        let spheres : Vec<((T,T,T), T)> = (0..num_shapes).map(|_| (gen_pos3(&mut rng), gen_rad(&mut rng))).collect();
        let capsules : Vec<((T,T,T), (T,T,T), T)> = (0..num_shapes).map(|_| (gen_pos3(&mut rng), gen_pos3(&mut rng), gen_rad(&mut rng))).collect();
        let segments : Vec<((T,T,T), (T,T,T))> = (0..num_shapes).map(|_| (gen_pos3(&mut rng), gen_pos3(&mut rng))).collect();
        let triangles : Vec<((T,T,T), (T,T,T), (T,T,T))> = (0..num_shapes).map(|_| (gen_pos3(&mut rng), gen_pos3(&mut rng), gen_pos3(&mut rng))).collect();

        if PRINT_CPP {
            println!("#pragma once");
            println!("#include \"by_copy.h\"\n");

            println!("namespace precomputed {{");

            println!("std::vector<TSphere> fixed_spheres = {{");
            for s in &spheres { println!("    {{ {{ {}, {}, {} }}, {} }},", (s.0).0, (s.0).1, (s.0).2, s.1); }
            println!("}}; // spheres\n");

            println!("std::vector<TCapsule> fixed_capsules = {{");
            for c in &capsules { println!("    {{ {{ {}, {}, {}, }}, {{ {}, {}, {} }}, {} }},", (c.0).0, (c.0).1, (c.0).2, (c.1).0, (c.1).1, (c.1).2, c.2) ; }
            println!("}}; // capsules\n");

            println!("std::vector<TSegment> fixed_segments = {{");
            for s in &segments { println!("    {{ {{ {}, {}, {}, }}, {{ {}, {}, {} }} }},", (s.0).0, (s.0).1, (s.0).2, (s.1).0, (s.1).1, (s.1).2) ; }
            println!("}}; // segments\n");

            println!("std::vector<TTriangle> fixed_triangles = {{");
            for t in &triangles { println!("    {{ {{ {}, {}, {}, }}, {{ {}, {}, {} }}, {{ {}, {}, {}, }} }},", (t.0).0, (t.0).1, (t.0).2, (t.1).0, (t.1).1, (t.1).2, (t.2).0, (t.2).1, (t.2).2); }
            println!("}}; // triangles\n");

            println!("}} // namespace precomputed");
            
            println!("/*");
        } 

        for run in 0..num_runs + num_warmup {
            let (overlaps, time) = by_copy::run_test(&spheres, &capsules, &segments, &triangles);
            total_overlap += overlaps;
            if run >= num_warmup {
                total_copy += time;
            }

            let (overlaps, time) = by_borrow::run_test(&spheres, &capsules, &segments, &triangles);
            total_overlap += overlaps;
            if run >= num_warmup {
                total_borrow += time;
            }
        }
    }

    println!("Totals:");
    println!("  Overlaps: {}", total_overlap);
    println!("  By-Copy: {}", total_copy);
    println!("  By-Borrow: {}\n", total_borrow);
    
    let total_copy = total_copy as f64;
    let total_borrow = total_borrow as f64;
    let delta = ((total_copy - total_borrow) / total_copy) * -100.0;
    println!("Delta: {}{:.3}%", if delta >= 0.0 { "+" } else { "" }, delta);
    
    if PRINT_CPP {
        println!("*/");
    }
}