1pub struct Vector3 {
49 pub(crate) v: cxx::UniquePtr<maliput_sys::math::ffi::Vector3>,
50}
51
52impl Vector3 {
53 pub fn new(x: f64, y: f64, z: f64) -> Vector3 {
55 Vector3 {
56 v: maliput_sys::math::ffi::Vector3_new(x, y, z),
57 }
58 }
59 pub fn x(&self) -> f64 {
61 self.v.x()
62 }
63 pub fn y(&self) -> f64 {
65 self.v.y()
66 }
67 pub fn z(&self) -> f64 {
69 self.v.z()
70 }
71 pub fn norm(&self) -> f64 {
73 self.v.norm()
74 }
75 pub fn normalize(&mut self) {
77 self.v.as_mut().expect("Unexpected error").normalize();
78 }
79 pub fn dot(&self, w: &Vector3) -> f64 {
81 maliput_sys::math::ffi::Vector3_dot(&self.v, &w.v)
82 }
83 pub fn cross(&self, w: &Vector3) -> Vector3 {
85 Vector3 {
86 v: maliput_sys::math::ffi::Vector3_cross(&self.v, &w.v),
87 }
88 }
89}
90
91impl PartialEq for Vector3 {
92 fn eq(&self, other: &Self) -> bool {
93 maliput_sys::math::ffi::Vector3_equals(&self.v, &other.v)
94 }
95}
96
97impl Eq for Vector3 {}
98
99impl std::fmt::Display for Vector3 {
100 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
101 write!(f, "{}", maliput_sys::math::ffi::Vector3_to_str(&self.v))
102 }
103}
104
105impl std::fmt::Debug for Vector3 {
106 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
107 f.debug_struct("Vector3")
108 .field("x", &self.x())
109 .field("y", &self.y())
110 .field("z", &self.z())
111 .finish()
112 }
113}
114
115pub struct Vector4 {
132 v: cxx::UniquePtr<maliput_sys::math::ffi::Vector4>,
133}
134
135impl Vector4 {
136 pub fn new(x: f64, y: f64, z: f64, w: f64) -> Vector4 {
138 Vector4 {
139 v: maliput_sys::math::ffi::Vector4_new(x, y, z, w),
140 }
141 }
142 pub fn x(&self) -> f64 {
144 self.v.x()
145 }
146 pub fn y(&self) -> f64 {
148 self.v.y()
149 }
150 pub fn z(&self) -> f64 {
152 self.v.z()
153 }
154 pub fn w(&self) -> f64 {
156 self.v.w()
157 }
158 pub fn norm(&self) -> f64 {
160 self.v.norm()
161 }
162 pub fn dot(&self, w: &Vector4) -> f64 {
164 maliput_sys::math::ffi::Vector4_dot(&self.v, &w.v)
165 }
166 pub fn normalize(&mut self) {
168 self.v.as_mut().expect("Unexpected error").normalize();
169 }
170}
171
172impl PartialEq for Vector4 {
173 fn eq(&self, other: &Self) -> bool {
174 maliput_sys::math::ffi::Vector4_equals(&self.v, &other.v)
175 }
176}
177
178impl Eq for Vector4 {}
179
180impl std::fmt::Display for Vector4 {
181 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
182 write!(f, "{}", maliput_sys::math::ffi::Vector4_to_str(&self.v))
183 }
184}
185
186impl std::fmt::Debug for Vector4 {
187 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
188 f.debug_struct("Vector4")
189 .field("x", &self.x())
190 .field("y", &self.y())
191 .field("z", &self.z())
192 .field("w", &self.z())
193 .finish()
194 }
195}
196
197pub struct Matrix3 {
212 m: cxx::UniquePtr<maliput_sys::math::ffi::Matrix3>,
213}
214
215impl Matrix3 {
216 pub fn new(row1: Vector3, row2: Vector3, row3: Vector3) -> Matrix3 {
218 Matrix3 {
219 m: maliput_sys::math::ffi::Matrix3_new(
220 row1.x(),
221 row1.y(),
222 row1.z(),
223 row2.x(),
224 row2.y(),
225 row2.z(),
226 row3.x(),
227 row3.y(),
228 row3.z(),
229 ),
230 }
231 }
232 pub fn cofactor(&self, row: usize, col: usize) -> f64 {
234 self.m.cofactor(row, col)
235 }
236 pub fn cofactor_matrix(&self) -> Matrix3 {
238 Matrix3 {
239 m: maliput_sys::math::ffi::Matrix3_cofactor_matrix(&self.m),
240 }
241 }
242 pub fn determinant(&self) -> f64 {
244 self.m.determinant()
245 }
246 pub fn is_singular(&self) -> bool {
248 self.m.is_singular()
249 }
250 pub fn row(&self, index: usize) -> Vector3 {
252 Vector3 {
253 v: maliput_sys::math::ffi::Matrix3_row(&self.m, index),
254 }
255 }
256 pub fn col(&self, index: usize) -> Vector3 {
258 Vector3 {
259 v: maliput_sys::math::ffi::Matrix3_col(&self.m, index),
260 }
261 }
262 pub fn transpose(&self) -> Matrix3 {
264 Matrix3 {
265 m: maliput_sys::math::ffi::Matrix3_transpose(&self.m),
266 }
267 }
268 pub fn adjoint(&self) -> Matrix3 {
270 Matrix3 {
271 m: maliput_sys::math::ffi::Matrix3_adjoint(&self.m),
272 }
273 }
274 pub fn inverse(&self) -> Matrix3 {
276 Matrix3 {
277 m: maliput_sys::math::ffi::Matrix3_inverse(&self.m),
278 }
279 }
280}
281
282impl PartialEq for Matrix3 {
283 fn eq(&self, other: &Self) -> bool {
284 maliput_sys::math::ffi::Matrix3_equals(&self.m, &other.m)
285 }
286}
287
288impl Eq for Matrix3 {}
289
290impl std::fmt::Display for Matrix3 {
291 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
292 write!(f, "{}", maliput_sys::math::ffi::Matrix3_to_str(&self.m))
293 }
294}
295
296impl std::fmt::Debug for Matrix3 {
297 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
298 f.debug_struct("Matrix3")
299 .field("row1", &self.row(0))
300 .field("row2", &self.row(1))
301 .field("row3", &self.row(2))
302 .finish()
303 }
304}
305
306pub struct Quaternion {
309 q: cxx::UniquePtr<maliput_sys::math::ffi::Quaternion>,
310}
311
312impl Quaternion {
313 pub fn new(w: f64, x: f64, y: f64, z: f64) -> Quaternion {
317 Quaternion {
318 q: maliput_sys::math::ffi::Quaternion_new(w, x, y, z),
319 }
320 }
321
322 pub fn w(&self) -> f64 {
324 self.q.w()
325 }
326
327 pub fn x(&self) -> f64 {
329 self.q.x()
330 }
331 pub fn y(&self) -> f64 {
333 self.q.y()
334 }
335 pub fn z(&self) -> f64 {
337 self.q.z()
338 }
339 pub fn vec(&self) -> Vector3 {
341 Vector3 {
342 v: maliput_sys::math::ffi::Quaternion_vec(&self.q),
343 }
344 }
345 pub fn coeffs(&self) -> Vector4 {
347 Vector4 {
348 v: maliput_sys::math::ffi::Quaternion_coeffs(&self.q),
349 }
350 }
351 pub fn dot(&self, other: &Quaternion) -> f64 {
353 self.q.dot(&other.q)
354 }
355 pub fn angular_distance(&self, other: &Quaternion) -> f64 {
357 self.q.AngularDistance(&other.q)
358 }
359 pub fn norm(&self) -> f64 {
361 self.q.norm()
362 }
363 pub fn normalize(&mut self) {
365 self.q.as_mut().expect("Unexpected error").normalize();
366 }
367 pub fn squared_norm(&self) -> f64 {
369 self.q.squared_norm()
370 }
371 pub fn inverse(&self) -> Quaternion {
373 Quaternion {
374 q: maliput_sys::math::ffi::Quaternion_Inverse(&self.q),
375 }
376 }
377 pub fn conjugate(&self) -> Quaternion {
379 Quaternion {
380 q: maliput_sys::math::ffi::Quaternion_conjugate(&self.q),
381 }
382 }
383 pub fn to_rotation_matrix(&self) -> Matrix3 {
385 let q = maliput_sys::math::ffi::Quaternion_ToRotationMatrix(&self.q);
386 Matrix3 { m: q }
387 }
388 pub fn transform_vector(&self, v: &Vector3) -> Vector3 {
390 let q = maliput_sys::math::ffi::Quaternion_TransformVector(&self.q, &v.v);
391 Vector3 { v: q }
392 }
393}
394
395impl PartialEq for Quaternion {
396 fn eq(&self, other: &Self) -> bool {
397 maliput_sys::math::ffi::Quaternion_equals(&self.q, &other.q)
398 }
399}
400
401impl Eq for Quaternion {}
402
403impl std::fmt::Display for Quaternion {
404 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
405 write!(f, "{}", maliput_sys::math::ffi::Quaternion_to_str(&self.q))
406 }
407}
408impl std::fmt::Debug for Quaternion {
409 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
410 f.debug_struct("Quaternion")
411 .field("w", &self.w())
412 .field("x", &self.x())
413 .field("y", &self.y())
414 .field("z", &self.z())
415 .finish()
416 }
417}
418
419pub struct RollPitchYaw {
434 rpy: cxx::UniquePtr<maliput_sys::math::ffi::RollPitchYaw>,
435}
436
437impl RollPitchYaw {
438 pub fn new(roll: f64, pitch: f64, yaw: f64) -> RollPitchYaw {
440 RollPitchYaw {
441 rpy: maliput_sys::math::ffi::RollPitchYaw_new(roll, pitch, yaw),
442 }
443 }
444 pub fn roll_angle(&self) -> f64 {
446 self.rpy.roll_angle()
447 }
448 pub fn pitch_angle(&self) -> f64 {
450 self.rpy.pitch_angle()
451 }
452 pub fn yaw_angle(&self) -> f64 {
454 self.rpy.yaw_angle()
455 }
456 pub fn vector(&self) -> Vector3 {
458 Vector3::new(self.rpy.vector().x(), self.rpy.vector().y(), self.rpy.vector().z())
459 }
460 pub fn set(&mut self, roll: f64, pitch: f64, yaw: f64) {
462 maliput_sys::math::ffi::RollPitchYaw_set(self.rpy.as_mut().expect("Unexpected Error"), roll, pitch, yaw);
463 }
464 pub fn set_from_quaternion(&mut self, q: &Quaternion) {
466 maliput_sys::math::ffi::RollPitchYaw_SetFromQuaternion(self.rpy.as_mut().expect("Unexpected Error"), &q.q);
467 }
468 pub fn to_quaternion(&self) -> Quaternion {
470 Quaternion {
471 q: maliput_sys::math::ffi::RollPitchYaw_ToQuaternion(&self.rpy),
472 }
473 }
474 pub fn to_matrix(&self) -> Matrix3 {
476 Matrix3 {
477 m: maliput_sys::math::ffi::RollPitchYaw_ToMatrix(&self.rpy),
478 }
479 }
480 pub fn calc_rotation_matrix_dt(&self, rpy_dt: &Vector3) -> Matrix3 {
498 Matrix3 {
499 m: maliput_sys::math::ffi::RollPitchYaw_CalcRotationMatrixDt(&self.rpy, &rpy_dt.v),
500 }
501 }
502}
503
504pub struct BoundingBox {
510 pub(crate) b: cxx::UniquePtr<maliput_sys::math::ffi::BoundingBox>,
511}
512
513impl BoundingBox {
514 pub fn new(position: &Vector3, box_size: &Vector3, orientation: &RollPitchYaw, tolerance: f64) -> BoundingBox {
522 BoundingBox {
523 b: maliput_sys::math::ffi::BoundingBox_new(&position.v, &box_size.v, &orientation.rpy, tolerance),
524 }
525 }
526
527 pub fn position(&self) -> Vector3 {
529 let p = maliput_sys::math::ffi::BoundingBox::position(&self.b);
530 Vector3::new(p.x(), p.y(), p.z())
531 }
532
533 pub fn box_size(&self) -> Vector3 {
535 let s = maliput_sys::math::ffi::BoundingBox::box_size(&self.b);
536 Vector3::new(s.x(), s.y(), s.z())
537 }
538
539 pub fn orientation(&self) -> RollPitchYaw {
541 let r = maliput_sys::math::ffi::BoundingBox::get_orientation(&self.b);
542 RollPitchYaw::new(r.roll_angle(), r.pitch_angle(), r.yaw_angle())
543 }
544
545 pub fn get_vertices(&self) -> Vec<Vector3> {
547 let verts = maliput_sys::math::ffi::BoundingBox_get_vertices(&self.b);
548 verts.iter().map(|v| Vector3::new(v.x(), v.y(), v.z())).collect()
549 }
550
551 pub fn is_box_contained(&self, other: &BoundingBox) -> bool {
553 maliput_sys::math::ffi::BoundingBox::IsBoxContained(&self.b, &other.b)
554 }
555
556 pub fn is_box_intersected(&self, other: &BoundingBox) -> bool {
558 maliput_sys::math::ffi::BoundingBox::IsBoxIntersected(&self.b, &other.b)
559 }
560}
561
562mod tests {
563 #[test]
564 fn vector3_new() {
565 let v = super::Vector3::new(1.0, 2.0, 3.0);
566 assert_eq!(v.x(), 1.0);
567 assert_eq!(v.y(), 2.0);
568 assert_eq!(v.z(), 3.0);
569 }
570
571 #[test]
572 fn vector3_equality() {
573 let v = super::Vector3::new(1.0, 2.0, 3.0);
574 let w = super::Vector3::new(1.0, 2.0, 3.0);
575 assert_eq!(v, w);
576 let z = super::Vector3::new(4.0, 5.0, 6.0);
577 assert_ne!(v, z);
578 }
579
580 #[test]
581 fn vector3_norm() {
582 let v = super::Vector3::new(1.0, 2.0, 3.0);
583 assert_eq!(v.norm(), (v.x() * v.x() + v.y() * v.y() + v.z() * v.z()).sqrt());
584 }
585
586 #[test]
587 fn vector3_normalize() {
588 let mut v = super::Vector3::new(1.0, 2.0, 3.0);
589 let norm = v.norm();
590 v.normalize();
591 assert_eq!(v.x(), 1.0 / norm);
592 assert_eq!(v.y(), 2.0 / norm);
593 assert_eq!(v.z(), 3.0 / norm);
594 }
595
596 #[test]
597 fn vector3_dot() {
598 let v = super::Vector3::new(1.0, 2.0, 3.0);
599 let w = super::Vector3::new(4.0, 5.0, 6.0);
600 assert_eq!(v.dot(&w), v.x() * w.x() + v.y() * w.y() + v.z() * w.z());
601 }
602
603 #[test]
604 fn vector3_cross() {
605 let v = super::Vector3::new(1.0, 2.0, 3.0);
606 let w = super::Vector3::new(4.0, 5.0, 6.0);
607 let cross = v.cross(&w);
608 assert_eq!(cross.x(), v.y() * w.z() - v.z() * w.y());
609 assert_eq!(cross.y(), v.z() * w.x() - v.x() * w.z());
610 assert_eq!(cross.z(), v.x() * w.y() - v.y() * w.x());
611 }
612
613 #[test]
614 fn vector4_new() {
615 let v = super::Vector4::new(1.0, 2.0, 3.0, 4.0);
616 assert_eq!(v.x(), 1.0);
617 assert_eq!(v.y(), 2.0);
618 assert_eq!(v.z(), 3.0);
619 assert_eq!(v.w(), 4.0);
620 }
621
622 #[test]
623 fn vector4_equality() {
624 let v = super::Vector4::new(1.0, 2.0, 3.0, 4.0);
625 let w = super::Vector4::new(1.0, 2.0, 3.0, 4.0);
626 assert_eq!(v, w);
627 let z = super::Vector4::new(4.0, 5.0, 6.0, 7.0);
628 assert_ne!(v, z);
629 }
630
631 #[test]
632 fn vector4_norm() {
633 let v = super::Vector4::new(1.0, 2.0, 3.0, 4.0);
634 assert_eq!(
635 v.norm(),
636 (v.x() * v.x() + v.y() * v.y() + v.z() * v.z() + v.w() * v.w()).sqrt()
637 );
638 }
639
640 #[test]
641 fn vector4_dot() {
642 let v = super::Vector4::new(1.0, 2.0, 3.0, 4.0);
643 let w = super::Vector4::new(4.0, 5.0, 6.0, 7.0);
644 assert_eq!(v.dot(&w), v.x() * w.x() + v.y() * w.y() + v.z() * w.z() + v.w() * w.w());
645 }
646
647 #[test]
648 fn vector4_normalize() {
649 let mut v = super::Vector4::new(1.0, 2.0, 3.0, 4.0);
650 let norm = v.norm();
651 v.normalize();
652 assert_eq!(v.x(), 1.0 / norm);
653 assert_eq!(v.y(), 2.0 / norm);
654 assert_eq!(v.z(), 3.0 / norm);
655 assert_eq!(v.w(), 4.0 / norm);
656 }
657
658 #[test]
659 fn matrix4_tests() {
660 let row_1 = super::Vector3::new(1.0, 2.0, 3.0);
661 let row_2 = super::Vector3::new(4.0, 5.0, 6.0);
662 let row_3 = super::Vector3::new(7.0, 8.0, 9.0);
663 let _m = super::Matrix3::new(row_1, row_2, row_3);
664 assert_eq!(_m.row(0).x(), 1.0);
665 assert_eq!(_m.col(2).z(), 9.0);
666 }
668
669 #[test]
670 fn quaternion_tests() {
671 let q = super::Quaternion::new(1.0, 2.0, 3.0, 4.0);
672 assert_eq!(q.w(), 1.0);
673 assert_eq!(q.x(), 2.0);
674 assert_eq!(q.y(), 3.0);
675 assert_eq!(q.z(), 4.0);
676 }
678
679 #[test]
680 fn roll_pitch_yaw_tests() {
681 let rpy = super::RollPitchYaw::new(1.0, 2.0, 3.0);
682 assert_eq!(rpy.roll_angle(), 1.0);
683 assert_eq!(rpy.pitch_angle(), 2.0);
684 assert_eq!(rpy.yaw_angle(), 3.0);
685 }
687
688 #[test]
689 fn bounding_box_new() {
690 let position = super::Vector3::new(1.0, 2.0, 3.0);
691 let box_size = super::Vector3::new(4.0, 5.0, 6.0);
692 let orientation = super::RollPitchYaw::new(0.1, 0.2, 0.3);
693 let tolerance = 1e-3;
694
695 let bb = super::BoundingBox::new(&position, &box_size, &orientation, tolerance);
696
697 assert_eq!(bb.position().x(), 1.0);
698 assert_eq!(bb.position().y(), 2.0);
699 assert_eq!(bb.position().z(), 3.0);
700
701 assert_eq!(bb.box_size().x(), 4.0);
702 assert_eq!(bb.box_size().y(), 5.0);
703 assert_eq!(bb.box_size().z(), 6.0);
704
705 assert_eq!(bb.orientation().roll_angle(), 0.1);
706 assert_eq!(bb.orientation().pitch_angle(), 0.2);
707 assert_eq!(bb.orientation().yaw_angle(), 0.3);
708 }
709
710 #[test]
711 fn bounding_box_position() {
712 let position = super::Vector3::new(1.0, 2.0, 3.0);
713 let box_size = super::Vector3::new(4.0, 5.0, 6.0);
714 let orientation = super::RollPitchYaw::new(0.0, 0.0, 0.0);
715 let bb = super::BoundingBox::new(&position, &box_size, &orientation, 1e-3);
716 assert_eq!(bb.position().x(), 1.0);
717 assert_eq!(bb.position().y(), 2.0);
718 assert_eq!(bb.position().z(), 3.0);
719 }
720
721 #[test]
722 fn bounding_box_box_size() {
723 let position = super::Vector3::new(0.0, 0.0, 0.0);
724 let box_size = super::Vector3::new(4.0, 5.0, 6.0);
725 let orientation = super::RollPitchYaw::new(0.0, 0.0, 0.0);
726 let bb = super::BoundingBox::new(&position, &box_size, &orientation, 1e-3);
727 assert_eq!(bb.box_size().x(), 4.0);
728 assert_eq!(bb.box_size().y(), 5.0);
729 assert_eq!(bb.box_size().z(), 6.0);
730 }
731
732 #[test]
733 fn bounding_box_orientation() {
734 let position = super::Vector3::new(0.0, 0.0, 0.0);
735 let box_size = super::Vector3::new(1.0, 1.0, 1.0);
736 let orientation = super::RollPitchYaw::new(0.1, 0.2, 0.3);
737 let bb = super::BoundingBox::new(&position, &box_size, &orientation, 1e-3);
738 assert_eq!(bb.orientation().roll_angle(), 0.1);
739 assert_eq!(bb.orientation().pitch_angle(), 0.2);
740 assert_eq!(bb.orientation().yaw_angle(), 0.3);
741 }
742
743 #[test]
744 fn bounding_box_get_vertices() {
745 let position = super::Vector3::new(0.0, 0.0, 0.0);
746 let box_size = super::Vector3::new(2.0, 2.0, 2.0);
747 let orientation = super::RollPitchYaw::new(0.0, 0.0, 0.0);
748 let bb = super::BoundingBox::new(&position, &box_size, &orientation, 1e-3);
749 let vertices = bb.get_vertices();
750 assert_eq!(vertices.len(), 8);
751 }
752
753 #[test]
754 fn bounding_box_is_box_contained() {
755 let origin = super::Vector3::new(0.0, 0.0, 0.0);
756 let identity = super::RollPitchYaw::new(0.0, 0.0, 0.0);
757 let big_box = super::BoundingBox::new(&origin, &super::Vector3::new(10.0, 10.0, 10.0), &identity, 1e-3);
758 let small_box = super::BoundingBox::new(&origin, &super::Vector3::new(1.0, 1.0, 1.0), &identity, 1e-3);
759 assert!(big_box.is_box_contained(&small_box));
760 assert!(!small_box.is_box_contained(&big_box));
761 }
762
763 #[test]
764 fn bounding_box_is_box_intersected() {
765 let identity = super::RollPitchYaw::new(0.0, 0.0, 0.0);
766 let box_a = super::BoundingBox::new(
767 &super::Vector3::new(0.0, 0.0, 0.0),
768 &super::Vector3::new(2.0, 2.0, 2.0),
769 &identity,
770 1e-3,
771 );
772 let box_b = super::BoundingBox::new(
773 &super::Vector3::new(1.0, 0.0, 0.0),
774 &super::Vector3::new(2.0, 2.0, 2.0),
775 &identity,
776 1e-3,
777 );
778 let box_c = super::BoundingBox::new(
779 &super::Vector3::new(100.0, 0.0, 0.0),
780 &super::Vector3::new(2.0, 2.0, 2.0),
781 &identity,
782 1e-3,
783 );
784 assert!(box_a.is_box_intersected(&box_b));
785 assert!(!box_a.is_box_intersected(&box_c));
786 }
787}