#![allow(
clippy::float_cmp,
reason = "the model-access witnesses compare exactly stored coordinates"
)]
use core::any::TypeId;
use boost_geometry::cs::{Cartesian, Degree, Geographic};
use boost_geometry::model::{
Box as ModelBox, InfiniteLine, Linestring, Point2D, Point3D, PointingSegment, Polygon,
PolyhedralSurface, Rebound, Ring,
};
use boost_geometry::prelude::{Point, PolyhedralSurface as _};
use boost_geometry::trait_::IndexedAccess;
#[test]
fn point_xyz_has_named_coordinate_access() {
let mut point2 = Point2D::<f64, Cartesian>::new(1.0, 2.0);
point2.set_x(7.0);
point2.set_y(8.0);
assert_eq!((point2.x(), point2.y()), (7.0, 8.0));
let mut point = Point3D::<f64, Cartesian>::new(1.0, 2.0, 3.0);
assert_eq!((point.x(), point.y(), point.z()), (1.0, 2.0, 3.0));
point.set_x(4.0);
point.set_y(5.0);
point.set_z(6.0);
assert_eq!(
(point.get::<0>(), point.get::<1>(), point.get::<2>()),
(4.0, 5.0, 6.0)
);
}
#[test]
fn pointing_segment_borrows_its_endpoints() {
let mut start = Point2D::<f64, Cartesian>::new(1.0, 2.0);
let mut end = Point2D::<f64, Cartesian>::new(3.0, 4.0);
{
let mut segment = PointingSegment::new(&mut start, &mut end);
assert_eq!((segment.start().x(), segment.start().y()), (1.0, 2.0));
assert_eq!((segment.end().x(), segment.end().y()), (3.0, 4.0));
assert_eq!(segment.get_indexed::<0, 0>(), 1.0);
assert_eq!(segment.get_indexed::<1, 1>(), 4.0);
segment.set_indexed::<0, 1>(8.0);
segment.set_indexed::<1, 0>(9.0);
}
assert_eq!(start.get::<1>(), 8.0);
assert_eq!(end.get::<0>(), 9.0);
}
#[test]
fn infinite_line_supports_reference_arithmetic() {
let horizontal = InfiniteLine::<f64>::from_coordinates(0.0, 0.0, 10.0, 0.0);
assert!(horizontal.side_value(5.0, 5.0) > 0.0);
assert!(horizontal.side_value(5.0, -5.0) < 0.0);
let first = InfiniteLine::<f64>::from_coordinates(5.0, 2.0, -7.0, 10.0);
let second = InfiniteLine::<f64>::from_coordinates(4.0, 7.0, 0.0, 1.0);
let intersection = first.intersection(&second).unwrap();
assert!((intersection.x() - 2.0).abs() < 1e-12);
assert!((intersection.y() - 4.0).abs() < 1e-12);
assert!(!first.is_degenerate());
assert!(InfiniteLine::<f64>::default().is_degenerate());
let start = Point2D::<f64, Cartesian>::new(0.0, 5.0);
let end = Point2D::<f64, Cartesian>::new(10.0, 5.0);
let from_points = InfiniteLine::from_points(&start, &end);
assert_eq!(from_points.side_value(3.0, 5.0), 0.0);
assert!(from_points.intersection(&horizontal).is_none());
}
#[test]
fn rebound_geometry_preserves_model_shape() {
type P = Point2D<f32, Cartesian>;
type B = ModelBox<P>;
type L = Linestring<P>;
type R = Ring<P, false, false>;
type Geo = Geographic<Degree>;
assert_eq!(
TypeId::of::<Rebound<P, f64, Geo>>(),
TypeId::of::<Point2D<f64, Geo>>()
);
assert_eq!(
TypeId::of::<Rebound<B, f64, Geo>>(),
TypeId::of::<ModelBox<Point2D<f64, Geo>>>()
);
assert_eq!(
TypeId::of::<Rebound<L, f64, Geo>>(),
TypeId::of::<Linestring<Point2D<f64, Geo>>>()
);
assert_eq!(
TypeId::of::<Rebound<R, f64, Geo>>(),
TypeId::of::<Ring<Point2D<f64, Geo>, false, false>>()
);
}
#[test]
fn polyhedral_surface_owns_faces() {
type P = Point3D<f64, Cartesian>;
type Face = Polygon<P>;
let face = Face::new(Ring::from_vec(vec![
P::new(0.0, 0.0, 0.0),
P::new(1.0, 0.0, 0.0),
P::new(0.0, 1.0, 0.0),
P::new(0.0, 0.0, 0.0),
]));
let empty = PolyhedralSurface::<Face>::default();
assert_eq!(empty.faces().len(), 0);
let mut surface = PolyhedralSurface::from_vec(vec![face.clone()]);
surface.push(face);
assert_eq!(surface.faces().len(), 2);
}