1 // Copyright 2022 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 use serde::{Deserialize, Serialize}; 16 17 type Centimeter = u32; 18 19 // A 3D position with coordinates in centimeters in quadrant I. 20 #[derive(Serialize, Deserialize, Debug)] 21 pub struct Position { 22 x: Centimeter, 23 y: Centimeter, 24 z: Centimeter, 25 } 26 27 impl Position { distance(&self, other: &Self) -> Centimeter28 pub fn distance(&self, other: &Self) -> Centimeter { 29 f32::sqrt( 30 ((self.x as i32 - other.x as i32).pow(2) 31 + (self.y as i32 - other.y as i32).pow(2) 32 + (self.z as i32 - other.z as i32).pow(2)) as f32, 33 ) 34 .round() as Centimeter 35 } 36 new(x: Centimeter, y: Centimeter, z: Centimeter) -> Position37 pub fn new(x: Centimeter, y: Centimeter, z: Centimeter) -> Position { 38 Position { x, y, z } 39 } 40 } 41 42 impl Default for Position { default() -> Self43 fn default() -> Self { 44 Self::new(0, 0, 0) 45 } 46 } 47 48 impl PartialEq<Position> for Position { 49 #[inline] eq(&self, other: &Self) -> bool50 fn eq(&self, other: &Self) -> bool { 51 self.x == other.x && self.y == other.y && self.z == other.z 52 } 53 } 54 55 #[cfg(test)] 56 mod tests { 57 use super::*; 58 59 #[test] distance_test()60 fn distance_test() { 61 // Example Pythagorean triples are (3, 4, 5), (5, 12, 13) .. 62 let a = Position::new(0, 0, 0); 63 let b = Position::new(0, 3, 4); 64 assert!(Position::distance(&a, &b) == 5); 65 let b = Position::new(0, 5, 12); 66 assert!(Position::distance(&a, &b) == 13); 67 } 68 #[test] default_test()69 fn default_test() { 70 let a = Position::default(); 71 assert!(a == Position { x: 0, y: 0, z: 0 }); 72 } 73 74 #[test] position_to_json()75 fn position_to_json() { 76 let data = Position::new(1, 2, 3); 77 let data_to_str = r#"{"x":1,"y":2,"z":3}"#; 78 let s = serde_json::to_string(&data).unwrap(); 79 assert_eq!(s, data_to_str) 80 } 81 } 82