Another project
0

Configure Feed

Select the types of activity you want to include in your feed.

at main 3.2 kB View raw
1use bone_solver::{ConstraintSystem, LineHandle, PointHandle, Residual, decompose}; 2use bone_types::{Parameter, ParameterIndex, ParentIndex, ResidualIndex}; 3 4fn p(i: u32) -> ParameterIndex { 5 ParameterIndex::new(i) 6} 7 8fn parent(i: u32) -> ParentIndex { 9 ParentIndex::new(i) 10} 11 12fn point(x: u32, y: u32) -> PointHandle { 13 PointHandle { x: p(x), y: p(y) } 14} 15 16fn parameters(values: &[f64]) -> Vec<Parameter> { 17 values.iter().copied().map(Parameter::new).collect() 18} 19 20#[test] 21fn disjoint_residuals_yield_separate_components() { 22 let system = ConstraintSystem::new( 23 parameters(&[0.0, 0.0, 1.0, 0.0, 10.0, 0.0, 11.0, 0.0]), 24 vec![ 25 Residual::Horizontal(LineHandle { 26 a: point(0, 1), 27 b: point(2, 3), 28 }), 29 Residual::Horizontal(LineHandle { 30 a: point(4, 5), 31 b: point(6, 7), 32 }), 33 ], 34 ); 35 let decomp = decompose(&system); 36 assert_eq!(decomp.components().len(), 2); 37 let first = &decomp.components()[0]; 38 let second = &decomp.components()[1]; 39 assert_eq!( 40 first 41 .parameters() 42 .iter() 43 .map(|p| p.value()) 44 .collect::<Vec<_>>(), 45 vec![0, 1, 2, 3] 46 ); 47 assert_eq!( 48 second 49 .parameters() 50 .iter() 51 .map(|p| p.value()) 52 .collect::<Vec<_>>(), 53 vec![4, 5, 6, 7] 54 ); 55 assert_eq!(first.residual_parents(), &[parent(0)]); 56 assert_eq!(second.residual_parents(), &[parent(1)]); 57 assert_eq!(first.residual_rows(&system), vec![ResidualIndex::new(0)]); 58 assert_eq!(second.residual_rows(&system), vec![ResidualIndex::new(1)]); 59} 60 61#[test] 62fn shared_parameter_merges_components() { 63 let system = ConstraintSystem::new( 64 parameters(&[0.0, 0.0, 1.0, 0.0, 2.0, 0.0]), 65 vec![ 66 Residual::Horizontal(LineHandle { 67 a: point(0, 1), 68 b: point(2, 3), 69 }), 70 Residual::Horizontal(LineHandle { 71 a: point(2, 3), 72 b: point(4, 5), 73 }), 74 ], 75 ); 76 let decomp = decompose(&system); 77 assert_eq!(decomp.components().len(), 1); 78 let only = &decomp.components()[0]; 79 assert_eq!(only.parameters().len(), 6); 80 assert_eq!(only.residual_parents(), &[parent(0), parent(1)]); 81} 82 83#[test] 84fn isolated_parameter_forms_its_own_component() { 85 let system = ConstraintSystem::new( 86 parameters(&[0.0, 0.0, 3.0]), 87 vec![Residual::Pin { 88 param: p(0), 89 target: 1.0, 90 }], 91 ); 92 let decomp = decompose(&system); 93 assert_eq!(decomp.components().len(), 3); 94 decomp 95 .components() 96 .iter() 97 .enumerate() 98 .for_each(|(i, comp)| { 99 let Ok(iv) = u32::try_from(i) else { 100 unreachable!() 101 }; 102 assert_eq!(comp.parameters(), &[ParameterIndex::new(iv)]); 103 }); 104 assert_eq!(decomp.components()[0].residual_parents(), &[parent(0)]); 105 assert!(decomp.components()[1].residual_parents().is_empty()); 106 assert!(decomp.components()[2].residual_parents().is_empty()); 107}