Skip to main content

bevy_math/
compass.rs

1use crate::Dir2;
2#[cfg(feature = "bevy_reflect")]
3use bevy_reflect::Reflect;
4#[cfg(all(feature = "serialize", feature = "bevy_reflect"))]
5use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
6use core::ops::Neg;
7use glam::Vec2;
8
9/// A compass enum with 4 directions.
10/// ```text
11///          N (North)
12///          ▲
13///          │
14///          │
15/// W (West) ┼─────► E (East)
16///          │
17///          │
18///          ▼
19///          S (South)
20/// ```
21#[derive(#[automatically_derived]
impl ::core::fmt::Debug for CompassQuadrant {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                CompassQuadrant::North => "North",
                CompassQuadrant::East => "East",
                CompassQuadrant::South => "South",
                CompassQuadrant::West => "West",
            })
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for CompassQuadrant {
    #[inline]
    fn clone(&self) -> CompassQuadrant { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CompassQuadrant { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for CompassQuadrant {
    #[inline]
    fn eq(&self, other: &CompassQuadrant) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for CompassQuadrant {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for CompassQuadrant {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash)]
22#[cfg_attr(feature = "serialize", derive(#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for CompassQuadrant {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                match *self {
                    CompassQuadrant::North =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "CompassQuadrant", 0u32, "North"),
                    CompassQuadrant::East =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "CompassQuadrant", 1u32, "East"),
                    CompassQuadrant::South =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "CompassQuadrant", 2u32, "South"),
                    CompassQuadrant::West =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "CompassQuadrant", 3u32, "West"),
                }
            }
        }
    };serde::Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for CompassQuadrant {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field { __field0, __field1, __field2, __field3, }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "variant identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            2u64 => _serde::__private228::Ok(__Field::__field2),
                            3u64 => _serde::__private228::Ok(__Field::__field3),
                            _ =>
                                _serde::__private228::Err(_serde::de::Error::invalid_value(_serde::de::Unexpected::Unsigned(__value),
                                        &"variant index 0 <= i < 4")),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "North" => _serde::__private228::Ok(__Field::__field0),
                            "East" => _serde::__private228::Ok(__Field::__field1),
                            "South" => _serde::__private228::Ok(__Field::__field2),
                            "West" => _serde::__private228::Ok(__Field::__field3),
                            _ => {
                                _serde::__private228::Err(_serde::de::Error::unknown_variant(__value,
                                        VARIANTS))
                            }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"North" => _serde::__private228::Ok(__Field::__field0),
                            b"East" => _serde::__private228::Ok(__Field::__field1),
                            b"South" => _serde::__private228::Ok(__Field::__field2),
                            b"West" => _serde::__private228::Ok(__Field::__field3),
                            _ => {
                                let __value =
                                    &_serde::__private228::from_utf8_lossy(__value);
                                _serde::__private228::Err(_serde::de::Error::unknown_variant(__value,
                                        VARIANTS))
                            }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<CompassQuadrant>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = CompassQuadrant;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "enum CompassQuadrant")
                    }
                    fn visit_enum<__A>(self, __data: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::EnumAccess<'de> {
                        match _serde::de::EnumAccess::variant(__data)? {
                            (__Field::__field0, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(CompassQuadrant::North)
                            }
                            (__Field::__field1, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(CompassQuadrant::East)
                            }
                            (__Field::__field2, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(CompassQuadrant::South)
                            }
                            (__Field::__field3, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(CompassQuadrant::West)
                            }
                        }
                    }
                }
                #[doc(hidden)]
                const VARIANTS: &'static [&'static str] =
                    &["North", "East", "South", "West"];
                _serde::Deserializer::deserialize_enum(__deserializer,
                    "CompassQuadrant", VARIANTS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<CompassQuadrant>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };serde::Deserialize))]
23#[cfg_attr(
24    feature = "bevy_reflect",
25    derive(const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for CompassQuadrant where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
                registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
                registration.register_type_data::<ReflectDeserialize, Self>();
                registration.register_type_data::<ReflectSerialize, Self>();
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {}
        }
        impl bevy_reflect::Typed for CompassQuadrant where  {
            #[inline]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(||
                        {
                            bevy_reflect::TypeInfo::Enum(bevy_reflect::enums::EnumInfo::new::<Self>(&[bevy_reflect::enums::VariantInfo::Unit(bevy_reflect::enums::UnitVariantInfo::new("North")),
                                                bevy_reflect::enums::VariantInfo::Unit(bevy_reflect::enums::UnitVariantInfo::new("East")),
                                                bevy_reflect::enums::VariantInfo::Unit(bevy_reflect::enums::UnitVariantInfo::new("South")),
                                                bevy_reflect::enums::VariantInfo::Unit(bevy_reflect::enums::UnitVariantInfo::new("West"))]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for CompassQuadrant where  {
            fn type_path() -> &'static str {
                "bevy_math::compass::CompassQuadrant"
            }
            fn short_type_path() -> &'static str { "CompassQuadrant" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("CompassQuadrant")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_math::compass".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_math::compass")
            }
        }
        impl bevy_reflect::Reflect for CompassQuadrant where  {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        impl bevy_reflect::enums::Enum for CompassQuadrant where  {
            fn field(&self, __name_param: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match self { _ => ::core::option::Option::None, }
            }
            fn field_at(&self, __index_param: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match self { _ => ::core::option::Option::None, }
            }
            fn field_mut(&mut self, __name_param: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match self { _ => ::core::option::Option::None, }
            }
            fn field_at_mut(&mut self, __index_param: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match self { _ => ::core::option::Option::None, }
            }
            fn index_of(&self, __name_param: &str)
                -> ::core::option::Option<usize> {
                match self { _ => ::core::option::Option::None, }
            }
            fn name_at(&self, __index_param: usize)
                -> ::core::option::Option<&str> {
                match self { _ => ::core::option::Option::None, }
            }
            fn iter_fields(&self) -> bevy_reflect::enums::VariantFieldIter {
                bevy_reflect::enums::VariantFieldIter::new(self)
            }
            #[inline]
            fn field_len(&self) -> usize {
                match self {
                    CompassQuadrant::North { .. } => 0usize,
                    CompassQuadrant::East { .. } => 0usize,
                    CompassQuadrant::South { .. } => 0usize,
                    CompassQuadrant::West { .. } => 0usize,
                    _ => 0,
                }
            }
            #[inline]
            fn variant_name(&self) -> &str {
                match self {
                    CompassQuadrant::North { .. } => "North",
                    CompassQuadrant::East { .. } => "East",
                    CompassQuadrant::South { .. } => "South",
                    CompassQuadrant::West { .. } => "West",
                    _ =>
                        ::core::panicking::panic("internal error: entered unreachable code"),
                }
            }
            #[inline]
            fn variant_index(&self) -> usize {
                match self {
                    CompassQuadrant::North { .. } => 0usize,
                    CompassQuadrant::East { .. } => 1usize,
                    CompassQuadrant::South { .. } => 2usize,
                    CompassQuadrant::West { .. } => 3usize,
                    _ =>
                        ::core::panicking::panic("internal error: entered unreachable code"),
                }
            }
            #[inline]
            fn variant_type(&self) -> bevy_reflect::enums::VariantType {
                match self {
                    CompassQuadrant::North { .. } =>
                        bevy_reflect::enums::VariantType::Unit,
                    CompassQuadrant::East { .. } =>
                        bevy_reflect::enums::VariantType::Unit,
                    CompassQuadrant::South { .. } =>
                        bevy_reflect::enums::VariantType::Unit,
                    CompassQuadrant::West { .. } =>
                        bevy_reflect::enums::VariantType::Unit,
                    _ =>
                        ::core::panicking::panic("internal error: entered unreachable code"),
                }
            }
            fn to_dynamic_enum(&self) -> bevy_reflect::enums::DynamicEnum {
                bevy_reflect::enums::DynamicEnum::from_ref::<Self>(self)
            }
        }
        impl bevy_reflect::PartialReflect for CompassQuadrant where  {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self,
                __value_param: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Enum(__value_param) =
                        bevy_reflect::PartialReflect::reflect_ref(__value_param) {
                    if bevy_reflect::enums::Enum::variant_name(self) ==
                            bevy_reflect::enums::Enum::variant_name(__value_param) {
                        match bevy_reflect::enums::Enum::variant_type(__value_param)
                            {
                            bevy_reflect::enums::VariantType::Struct => {
                                for field in
                                    bevy_reflect::enums::Enum::iter_fields(__value_param) {
                                    let name = field.name().unwrap();
                                    if let ::core::option::Option::Some(v) =
                                            bevy_reflect::enums::Enum::field_mut(self, name) {
                                        bevy_reflect::PartialReflect::try_apply(v, field.value())?;
                                    }
                                }
                            }
                            bevy_reflect::enums::VariantType::Tuple => {
                                for (index, field) in
                                    ::core::iter::Iterator::enumerate(bevy_reflect::enums::Enum::iter_fields(__value_param))
                                    {
                                    if let ::core::option::Option::Some(v) =
                                            bevy_reflect::enums::Enum::field_at_mut(self, index) {
                                        bevy_reflect::PartialReflect::try_apply(v, field.value())?;
                                    }
                                }
                            }
                            _ => {}
                        }
                    } else {
                        match bevy_reflect::enums::Enum::variant_name(__value_param)
                            {
                            "North" => { *self = CompassQuadrant::North {} }
                            "East" => { *self = CompassQuadrant::East {} }
                            "South" => { *self = CompassQuadrant::South {} }
                            "West" => { *self = CompassQuadrant::West {} }
                            name => {
                                return ::core::result::Result::Err(bevy_reflect::ApplyError::UnknownVariant {
                                            enum_name: ::core::convert::Into::into(bevy_reflect::DynamicTypePath::reflect_type_path(self)),
                                            variant_name: ::core::convert::Into::into(name),
                                        });
                            }
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(__value_param),
                                to_kind: bevy_reflect::ReflectKind::Enum,
                            });
                }
                ::core::result::Result::Ok(())
            }
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Enum
            }
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Enum(self)
            }
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Enum(self)
            }
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Enum(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_hash(&self) -> ::core::option::Option<u64> {
                use ::core::hash::{Hash, Hasher};
                let mut hasher = bevy_reflect::utility::reflect_hasher();
                Hash::hash(&::core::any::Any::type_id(self), &mut hasher);
                Hash::hash(self, &mut hasher);
                ::core::option::Option::Some(Hasher::finish(&hasher))
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                let value =
                    <dyn bevy_reflect::PartialReflect>::try_downcast_ref::<Self>(value);
                if let ::core::option::Option::Some(value) = value {
                    ::core::option::Option::Some(::core::cmp::PartialEq::eq(self,
                            value))
                } else { ::core::option::Option::Some(false) }
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::enums::enum_partial_cmp)(self, value)
            }
            fn debug(&self, f: &mut ::core::fmt::Formatter<'_>)
                -> ::core::fmt::Result {
                ::core::fmt::Debug::fmt(self, f)
            }
            #[inline]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(::core::clone::Clone::clone(self)))
            }
        }
        impl bevy_reflect::FromReflect for CompassQuadrant where  {
            fn from_reflect(__param0: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Enum(__param0) =
                        bevy_reflect::PartialReflect::reflect_ref(__param0) {
                    match bevy_reflect::enums::Enum::variant_name(__param0) {
                        "North" =>
                            ::core::option::Option::Some(CompassQuadrant::North {}),
                        "East" =>
                            ::core::option::Option::Some(CompassQuadrant::East {}),
                        "South" =>
                            ::core::option::Option::Some(CompassQuadrant::South {}),
                        "West" =>
                            ::core::option::Option::Some(CompassQuadrant::West {}),
                        name => ::core::option::Option::None,
                    }
                } else { ::core::option::Option::None }
            }
        }
    };Reflect),
26    reflect(Debug, PartialEq, Hash, Clone)
27)]
28#[cfg_attr(
29    all(feature = "serialize", feature = "bevy_reflect"),
30    reflect(Deserialize, Serialize)
31)]
32pub enum CompassQuadrant {
33    /// Corresponds to [`Dir2::Y`] and [`Dir2::NORTH`]
34    North,
35    /// Corresponds to [`Dir2::X`] and [`Dir2::EAST`]
36    East,
37    /// Corresponds to [`Dir2::NEG_Y`] and [`Dir2::SOUTH`]
38    South,
39    /// Corresponds to [`Dir2::NEG_X`] and [`Dir2::WEST`]
40    West,
41}
42
43impl CompassQuadrant {
44    /// Converts a standard index to a [`CompassQuadrant`].
45    ///
46    /// Starts at 0 for [`CompassQuadrant::North`] and increments clockwise.
47    pub const fn from_index(index: usize) -> Option<Self> {
48        match index {
49            0 => Some(Self::North),
50            1 => Some(Self::East),
51            2 => Some(Self::South),
52            3 => Some(Self::West),
53            _ => None,
54        }
55    }
56
57    /// Converts a [`CompassQuadrant`] to a standard index.
58    ///
59    /// Starts at 0 for [`CompassQuadrant::North`] and increments clockwise.
60    pub const fn to_index(self) -> usize {
61        match self {
62            Self::North => 0,
63            Self::East => 1,
64            Self::South => 2,
65            Self::West => 3,
66        }
67    }
68
69    /// Returns the opposite [`CompassQuadrant`], located 180 degrees from `self`.
70    ///
71    /// This can also be accessed via the `-` operator, using the [`Neg`] trait.
72    pub const fn opposite(&self) -> CompassQuadrant {
73        match self {
74            Self::North => Self::South,
75            Self::East => Self::West,
76            Self::South => Self::North,
77            Self::West => Self::East,
78        }
79    }
80
81    /// Checks if a point is in the direction represented by this [`CompassQuadrant`] from an origin.
82    ///
83    /// This uses a cone-based check: the vector from origin to the candidate point
84    /// must have a positive dot product with the direction vector.
85    ///
86    /// Uses standard mathematical coordinates where Y increases upward.
87    ///
88    /// # Arguments
89    ///
90    /// * `origin` - The starting position
91    /// * `candidate` - The target position to check
92    ///
93    /// # Returns
94    ///
95    /// `true` if the candidate is generally in the direction of this quadrant from the origin.
96    ///
97    /// # Example
98    ///
99    /// ```
100    /// use bevy_math::{CompassQuadrant, Vec2};
101    ///
102    /// let origin = Vec2::new(0.0, 0.0);
103    /// let north_point = Vec2::new(0.0, 10.0);  // Above origin (Y+ = up)
104    /// let east_point = Vec2::new(10.0, 0.0);   // Right of origin
105    ///
106    /// assert!(CompassQuadrant::North.is_in_direction(origin, north_point));
107    /// assert!(!CompassQuadrant::North.is_in_direction(origin, east_point));
108    /// ```
109    pub fn is_in_direction(self, origin: Vec2, candidate: Vec2) -> bool {
110        let dir = Dir2::from(self);
111        let to_candidate = candidate - origin;
112        to_candidate.dot(*dir) > 0.0
113    }
114}
115
116/// A compass enum with 8 directions.
117/// ```text
118///          N (North)
119///          ▲
120///     NW   │   NE
121///        ╲ │ ╱
122/// W (West) ┼─────► E (East)
123///        ╱ │ ╲
124///     SW   │   SE
125///          ▼
126///          S (South)
127/// ```
128#[derive(#[automatically_derived]
impl ::core::fmt::Debug for CompassOctant {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                CompassOctant::North => "North",
                CompassOctant::NorthEast => "NorthEast",
                CompassOctant::East => "East",
                CompassOctant::SouthEast => "SouthEast",
                CompassOctant::South => "South",
                CompassOctant::SouthWest => "SouthWest",
                CompassOctant::West => "West",
                CompassOctant::NorthWest => "NorthWest",
            })
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for CompassOctant {
    #[inline]
    fn clone(&self) -> CompassOctant { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CompassOctant { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for CompassOctant {
    #[inline]
    fn eq(&self, other: &CompassOctant) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for CompassOctant {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for CompassOctant {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash)]
129#[cfg_attr(feature = "serialize", derive(#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for CompassOctant {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                match *self {
                    CompassOctant::North =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "CompassOctant", 0u32, "North"),
                    CompassOctant::NorthEast =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "CompassOctant", 1u32, "NorthEast"),
                    CompassOctant::East =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "CompassOctant", 2u32, "East"),
                    CompassOctant::SouthEast =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "CompassOctant", 3u32, "SouthEast"),
                    CompassOctant::South =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "CompassOctant", 4u32, "South"),
                    CompassOctant::SouthWest =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "CompassOctant", 5u32, "SouthWest"),
                    CompassOctant::West =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "CompassOctant", 6u32, "West"),
                    CompassOctant::NorthWest =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "CompassOctant", 7u32, "NorthWest"),
                }
            }
        }
    };serde::Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for CompassOctant {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field {
                    __field0,
                    __field1,
                    __field2,
                    __field3,
                    __field4,
                    __field5,
                    __field6,
                    __field7,
                }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "variant identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            2u64 => _serde::__private228::Ok(__Field::__field2),
                            3u64 => _serde::__private228::Ok(__Field::__field3),
                            4u64 => _serde::__private228::Ok(__Field::__field4),
                            5u64 => _serde::__private228::Ok(__Field::__field5),
                            6u64 => _serde::__private228::Ok(__Field::__field6),
                            7u64 => _serde::__private228::Ok(__Field::__field7),
                            _ =>
                                _serde::__private228::Err(_serde::de::Error::invalid_value(_serde::de::Unexpected::Unsigned(__value),
                                        &"variant index 0 <= i < 8")),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "North" => _serde::__private228::Ok(__Field::__field0),
                            "NorthEast" => _serde::__private228::Ok(__Field::__field1),
                            "East" => _serde::__private228::Ok(__Field::__field2),
                            "SouthEast" => _serde::__private228::Ok(__Field::__field3),
                            "South" => _serde::__private228::Ok(__Field::__field4),
                            "SouthWest" => _serde::__private228::Ok(__Field::__field5),
                            "West" => _serde::__private228::Ok(__Field::__field6),
                            "NorthWest" => _serde::__private228::Ok(__Field::__field7),
                            _ => {
                                _serde::__private228::Err(_serde::de::Error::unknown_variant(__value,
                                        VARIANTS))
                            }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"North" => _serde::__private228::Ok(__Field::__field0),
                            b"NorthEast" => _serde::__private228::Ok(__Field::__field1),
                            b"East" => _serde::__private228::Ok(__Field::__field2),
                            b"SouthEast" => _serde::__private228::Ok(__Field::__field3),
                            b"South" => _serde::__private228::Ok(__Field::__field4),
                            b"SouthWest" => _serde::__private228::Ok(__Field::__field5),
                            b"West" => _serde::__private228::Ok(__Field::__field6),
                            b"NorthWest" => _serde::__private228::Ok(__Field::__field7),
                            _ => {
                                let __value =
                                    &_serde::__private228::from_utf8_lossy(__value);
                                _serde::__private228::Err(_serde::de::Error::unknown_variant(__value,
                                        VARIANTS))
                            }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<CompassOctant>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = CompassOctant;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "enum CompassOctant")
                    }
                    fn visit_enum<__A>(self, __data: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::EnumAccess<'de> {
                        match _serde::de::EnumAccess::variant(__data)? {
                            (__Field::__field0, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(CompassOctant::North)
                            }
                            (__Field::__field1, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(CompassOctant::NorthEast)
                            }
                            (__Field::__field2, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(CompassOctant::East)
                            }
                            (__Field::__field3, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(CompassOctant::SouthEast)
                            }
                            (__Field::__field4, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(CompassOctant::South)
                            }
                            (__Field::__field5, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(CompassOctant::SouthWest)
                            }
                            (__Field::__field6, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(CompassOctant::West)
                            }
                            (__Field::__field7, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(CompassOctant::NorthWest)
                            }
                        }
                    }
                }
                #[doc(hidden)]
                const VARIANTS: &'static [&'static str] =
                    &["North", "NorthEast", "East", "SouthEast", "South",
                                "SouthWest", "West", "NorthWest"];
                _serde::Deserializer::deserialize_enum(__deserializer,
                    "CompassOctant", VARIANTS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<CompassOctant>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };serde::Deserialize))]
130#[cfg_attr(
131    feature = "bevy_reflect",
132    derive(const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for CompassOctant where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
                registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
                registration.register_type_data::<ReflectDeserialize, Self>();
                registration.register_type_data::<ReflectSerialize, Self>();
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {}
        }
        impl bevy_reflect::Typed for CompassOctant where  {
            #[inline]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(||
                        {
                            bevy_reflect::TypeInfo::Enum(bevy_reflect::enums::EnumInfo::new::<Self>(&[bevy_reflect::enums::VariantInfo::Unit(bevy_reflect::enums::UnitVariantInfo::new("North")),
                                                bevy_reflect::enums::VariantInfo::Unit(bevy_reflect::enums::UnitVariantInfo::new("NorthEast")),
                                                bevy_reflect::enums::VariantInfo::Unit(bevy_reflect::enums::UnitVariantInfo::new("East")),
                                                bevy_reflect::enums::VariantInfo::Unit(bevy_reflect::enums::UnitVariantInfo::new("SouthEast")),
                                                bevy_reflect::enums::VariantInfo::Unit(bevy_reflect::enums::UnitVariantInfo::new("South")),
                                                bevy_reflect::enums::VariantInfo::Unit(bevy_reflect::enums::UnitVariantInfo::new("SouthWest")),
                                                bevy_reflect::enums::VariantInfo::Unit(bevy_reflect::enums::UnitVariantInfo::new("West")),
                                                bevy_reflect::enums::VariantInfo::Unit(bevy_reflect::enums::UnitVariantInfo::new("NorthWest"))]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for CompassOctant where  {
            fn type_path() -> &'static str {
                "bevy_math::compass::CompassOctant"
            }
            fn short_type_path() -> &'static str { "CompassOctant" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("CompassOctant")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_math::compass".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_math::compass")
            }
        }
        impl bevy_reflect::Reflect for CompassOctant where  {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        impl bevy_reflect::enums::Enum for CompassOctant where  {
            fn field(&self, __name_param: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match self { _ => ::core::option::Option::None, }
            }
            fn field_at(&self, __index_param: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match self { _ => ::core::option::Option::None, }
            }
            fn field_mut(&mut self, __name_param: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match self { _ => ::core::option::Option::None, }
            }
            fn field_at_mut(&mut self, __index_param: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match self { _ => ::core::option::Option::None, }
            }
            fn index_of(&self, __name_param: &str)
                -> ::core::option::Option<usize> {
                match self { _ => ::core::option::Option::None, }
            }
            fn name_at(&self, __index_param: usize)
                -> ::core::option::Option<&str> {
                match self { _ => ::core::option::Option::None, }
            }
            fn iter_fields(&self) -> bevy_reflect::enums::VariantFieldIter {
                bevy_reflect::enums::VariantFieldIter::new(self)
            }
            #[inline]
            fn field_len(&self) -> usize {
                match self {
                    CompassOctant::North { .. } => 0usize,
                    CompassOctant::NorthEast { .. } => 0usize,
                    CompassOctant::East { .. } => 0usize,
                    CompassOctant::SouthEast { .. } => 0usize,
                    CompassOctant::South { .. } => 0usize,
                    CompassOctant::SouthWest { .. } => 0usize,
                    CompassOctant::West { .. } => 0usize,
                    CompassOctant::NorthWest { .. } => 0usize,
                    _ => 0,
                }
            }
            #[inline]
            fn variant_name(&self) -> &str {
                match self {
                    CompassOctant::North { .. } => "North",
                    CompassOctant::NorthEast { .. } => "NorthEast",
                    CompassOctant::East { .. } => "East",
                    CompassOctant::SouthEast { .. } => "SouthEast",
                    CompassOctant::South { .. } => "South",
                    CompassOctant::SouthWest { .. } => "SouthWest",
                    CompassOctant::West { .. } => "West",
                    CompassOctant::NorthWest { .. } => "NorthWest",
                    _ =>
                        ::core::panicking::panic("internal error: entered unreachable code"),
                }
            }
            #[inline]
            fn variant_index(&self) -> usize {
                match self {
                    CompassOctant::North { .. } => 0usize,
                    CompassOctant::NorthEast { .. } => 1usize,
                    CompassOctant::East { .. } => 2usize,
                    CompassOctant::SouthEast { .. } => 3usize,
                    CompassOctant::South { .. } => 4usize,
                    CompassOctant::SouthWest { .. } => 5usize,
                    CompassOctant::West { .. } => 6usize,
                    CompassOctant::NorthWest { .. } => 7usize,
                    _ =>
                        ::core::panicking::panic("internal error: entered unreachable code"),
                }
            }
            #[inline]
            fn variant_type(&self) -> bevy_reflect::enums::VariantType {
                match self {
                    CompassOctant::North { .. } =>
                        bevy_reflect::enums::VariantType::Unit,
                    CompassOctant::NorthEast { .. } =>
                        bevy_reflect::enums::VariantType::Unit,
                    CompassOctant::East { .. } =>
                        bevy_reflect::enums::VariantType::Unit,
                    CompassOctant::SouthEast { .. } =>
                        bevy_reflect::enums::VariantType::Unit,
                    CompassOctant::South { .. } =>
                        bevy_reflect::enums::VariantType::Unit,
                    CompassOctant::SouthWest { .. } =>
                        bevy_reflect::enums::VariantType::Unit,
                    CompassOctant::West { .. } =>
                        bevy_reflect::enums::VariantType::Unit,
                    CompassOctant::NorthWest { .. } =>
                        bevy_reflect::enums::VariantType::Unit,
                    _ =>
                        ::core::panicking::panic("internal error: entered unreachable code"),
                }
            }
            fn to_dynamic_enum(&self) -> bevy_reflect::enums::DynamicEnum {
                bevy_reflect::enums::DynamicEnum::from_ref::<Self>(self)
            }
        }
        impl bevy_reflect::PartialReflect for CompassOctant where  {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self,
                __value_param: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Enum(__value_param) =
                        bevy_reflect::PartialReflect::reflect_ref(__value_param) {
                    if bevy_reflect::enums::Enum::variant_name(self) ==
                            bevy_reflect::enums::Enum::variant_name(__value_param) {
                        match bevy_reflect::enums::Enum::variant_type(__value_param)
                            {
                            bevy_reflect::enums::VariantType::Struct => {
                                for field in
                                    bevy_reflect::enums::Enum::iter_fields(__value_param) {
                                    let name = field.name().unwrap();
                                    if let ::core::option::Option::Some(v) =
                                            bevy_reflect::enums::Enum::field_mut(self, name) {
                                        bevy_reflect::PartialReflect::try_apply(v, field.value())?;
                                    }
                                }
                            }
                            bevy_reflect::enums::VariantType::Tuple => {
                                for (index, field) in
                                    ::core::iter::Iterator::enumerate(bevy_reflect::enums::Enum::iter_fields(__value_param))
                                    {
                                    if let ::core::option::Option::Some(v) =
                                            bevy_reflect::enums::Enum::field_at_mut(self, index) {
                                        bevy_reflect::PartialReflect::try_apply(v, field.value())?;
                                    }
                                }
                            }
                            _ => {}
                        }
                    } else {
                        match bevy_reflect::enums::Enum::variant_name(__value_param)
                            {
                            "North" => { *self = CompassOctant::North {} }
                            "NorthEast" => { *self = CompassOctant::NorthEast {} }
                            "East" => { *self = CompassOctant::East {} }
                            "SouthEast" => { *self = CompassOctant::SouthEast {} }
                            "South" => { *self = CompassOctant::South {} }
                            "SouthWest" => { *self = CompassOctant::SouthWest {} }
                            "West" => { *self = CompassOctant::West {} }
                            "NorthWest" => { *self = CompassOctant::NorthWest {} }
                            name => {
                                return ::core::result::Result::Err(bevy_reflect::ApplyError::UnknownVariant {
                                            enum_name: ::core::convert::Into::into(bevy_reflect::DynamicTypePath::reflect_type_path(self)),
                                            variant_name: ::core::convert::Into::into(name),
                                        });
                            }
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(__value_param),
                                to_kind: bevy_reflect::ReflectKind::Enum,
                            });
                }
                ::core::result::Result::Ok(())
            }
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Enum
            }
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Enum(self)
            }
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Enum(self)
            }
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Enum(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_hash(&self) -> ::core::option::Option<u64> {
                use ::core::hash::{Hash, Hasher};
                let mut hasher = bevy_reflect::utility::reflect_hasher();
                Hash::hash(&::core::any::Any::type_id(self), &mut hasher);
                Hash::hash(self, &mut hasher);
                ::core::option::Option::Some(Hasher::finish(&hasher))
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                let value =
                    <dyn bevy_reflect::PartialReflect>::try_downcast_ref::<Self>(value);
                if let ::core::option::Option::Some(value) = value {
                    ::core::option::Option::Some(::core::cmp::PartialEq::eq(self,
                            value))
                } else { ::core::option::Option::Some(false) }
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::enums::enum_partial_cmp)(self, value)
            }
            fn debug(&self, f: &mut ::core::fmt::Formatter<'_>)
                -> ::core::fmt::Result {
                ::core::fmt::Debug::fmt(self, f)
            }
            #[inline]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(::core::clone::Clone::clone(self)))
            }
        }
        impl bevy_reflect::FromReflect for CompassOctant where  {
            fn from_reflect(__param0: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Enum(__param0) =
                        bevy_reflect::PartialReflect::reflect_ref(__param0) {
                    match bevy_reflect::enums::Enum::variant_name(__param0) {
                        "North" =>
                            ::core::option::Option::Some(CompassOctant::North {}),
                        "NorthEast" =>
                            ::core::option::Option::Some(CompassOctant::NorthEast {}),
                        "East" =>
                            ::core::option::Option::Some(CompassOctant::East {}),
                        "SouthEast" =>
                            ::core::option::Option::Some(CompassOctant::SouthEast {}),
                        "South" =>
                            ::core::option::Option::Some(CompassOctant::South {}),
                        "SouthWest" =>
                            ::core::option::Option::Some(CompassOctant::SouthWest {}),
                        "West" =>
                            ::core::option::Option::Some(CompassOctant::West {}),
                        "NorthWest" =>
                            ::core::option::Option::Some(CompassOctant::NorthWest {}),
                        name => ::core::option::Option::None,
                    }
                } else { ::core::option::Option::None }
            }
        }
    };Reflect),
133    reflect(Debug, PartialEq, Hash, Clone)
134)]
135#[cfg_attr(
136    all(feature = "serialize", feature = "bevy_reflect"),
137    reflect(Deserialize, Serialize)
138)]
139pub enum CompassOctant {
140    /// Corresponds to [`Dir2::Y`] and [`Dir2::NORTH`]
141    North,
142    /// Corresponds to [`Dir2::NORTH_EAST`]
143    NorthEast,
144    /// Corresponds to [`Dir2::X`] and [`Dir2::EAST`]
145    East,
146    /// Corresponds to [`Dir2::SOUTH_EAST`]
147    SouthEast,
148    /// Corresponds to [`Dir2::NEG_Y`] and [`Dir2::SOUTH`]
149    South,
150    /// Corresponds to [`Dir2::SOUTH_WEST`]
151    SouthWest,
152    /// Corresponds to [`Dir2::NEG_X`] and [`Dir2::WEST`]
153    West,
154    /// Corresponds to [`Dir2::NORTH_WEST`]
155    NorthWest,
156}
157
158impl CompassOctant {
159    /// Converts a standard index to a [`CompassOctant`].
160    ///
161    /// Starts at 0 for [`CompassOctant::North`] and increments clockwise.
162    pub const fn from_index(index: usize) -> Option<Self> {
163        match index {
164            0 => Some(Self::North),
165            1 => Some(Self::NorthEast),
166            2 => Some(Self::East),
167            3 => Some(Self::SouthEast),
168            4 => Some(Self::South),
169            5 => Some(Self::SouthWest),
170            6 => Some(Self::West),
171            7 => Some(Self::NorthWest),
172            _ => None,
173        }
174    }
175
176    /// Converts a [`CompassOctant`] to a standard index.
177    ///
178    /// Starts at 0 for [`CompassOctant::North`] and increments clockwise.
179    pub const fn to_index(self) -> usize {
180        match self {
181            Self::North => 0,
182            Self::NorthEast => 1,
183            Self::East => 2,
184            Self::SouthEast => 3,
185            Self::South => 4,
186            Self::SouthWest => 5,
187            Self::West => 6,
188            Self::NorthWest => 7,
189        }
190    }
191
192    /// Returns the opposite [`CompassOctant`], located 180 degrees from `self`.
193    ///
194    /// This can also be accessed via the `-` operator, using the [`Neg`] trait.
195    pub const fn opposite(&self) -> CompassOctant {
196        match self {
197            Self::North => Self::South,
198            Self::NorthEast => Self::SouthWest,
199            Self::East => Self::West,
200            Self::SouthEast => Self::NorthWest,
201            Self::South => Self::North,
202            Self::SouthWest => Self::NorthEast,
203            Self::West => Self::East,
204            Self::NorthWest => Self::SouthEast,
205        }
206    }
207
208    /// Checks if a point is in the direction represented by this [`CompassOctant`] from an origin.
209    ///
210    /// This uses a cone-based check: the vector from origin to the candidate point
211    /// must have a positive dot product with the direction vector.
212    ///
213    /// Uses standard mathematical coordinates where Y increases upward.
214    ///
215    /// # Arguments
216    ///
217    /// * `origin` - The starting position
218    /// * `candidate` - The target position to check
219    ///
220    /// # Returns
221    ///
222    /// `true` if the candidate is generally in the direction of this octant from the origin.
223    ///
224    /// # Example
225    ///
226    /// ```
227    /// use bevy_math::{CompassOctant, Vec2};
228    ///
229    /// let origin = Vec2::new(0.0, 0.0);
230    /// let north_point = Vec2::new(0.0, 10.0);  // Above origin (Y+ = up)
231    /// let east_point = Vec2::new(10.0, 0.0);   // Right of origin
232    ///
233    /// assert!(CompassOctant::North.is_in_direction(origin, north_point));
234    /// assert!(!CompassOctant::North.is_in_direction(origin, east_point));
235    /// ```
236    pub fn is_in_direction(self, origin: Vec2, candidate: Vec2) -> bool {
237        let dir = Dir2::from(self);
238        let to_candidate = candidate - origin;
239        to_candidate.dot(*dir) > 0.0
240    }
241}
242
243impl From<CompassQuadrant> for Dir2 {
244    fn from(q: CompassQuadrant) -> Self {
245        match q {
246            CompassQuadrant::North => Dir2::NORTH,
247            CompassQuadrant::East => Dir2::EAST,
248            CompassQuadrant::South => Dir2::SOUTH,
249            CompassQuadrant::West => Dir2::WEST,
250        }
251    }
252}
253
254impl From<Dir2> for CompassQuadrant {
255    /// Converts a [`Dir2`] to a [`CompassQuadrant`] in a lossy manner.
256    /// Converting back to a [`Dir2`] is not guaranteed to yield the same value.
257    fn from(dir: Dir2) -> Self {
258        let angle = dir.to_angle().to_degrees();
259
260        match angle {
261            -135.0..=-45.0 => Self::South,
262            -45.0..=45.0 => Self::East,
263            45.0..=135.0 => Self::North,
264            135.0..=180.0 | -180.0..=-135.0 => Self::West,
265            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
266        }
267    }
268}
269
270impl From<CompassOctant> for Dir2 {
271    fn from(o: CompassOctant) -> Self {
272        match o {
273            CompassOctant::North => Dir2::NORTH,
274            CompassOctant::NorthEast => Dir2::NORTH_EAST,
275            CompassOctant::East => Dir2::EAST,
276            CompassOctant::SouthEast => Dir2::SOUTH_EAST,
277            CompassOctant::South => Dir2::SOUTH,
278            CompassOctant::SouthWest => Dir2::SOUTH_WEST,
279            CompassOctant::West => Dir2::WEST,
280            CompassOctant::NorthWest => Dir2::NORTH_WEST,
281        }
282    }
283}
284
285impl From<Dir2> for CompassOctant {
286    /// Converts a [`Dir2`] to a [`CompassOctant`] in a lossy manner.
287    /// Converting back to a [`Dir2`] is not guaranteed to yield the same value.
288    fn from(dir: Dir2) -> Self {
289        let angle = dir.to_angle().to_degrees();
290
291        match angle {
292            -112.5..=-67.5 => Self::South,
293            -67.5..=-22.5 => Self::SouthEast,
294            -22.5..=22.5 => Self::East,
295            22.5..=67.5 => Self::NorthEast,
296            67.5..=112.5 => Self::North,
297            112.5..=157.5 => Self::NorthWest,
298            157.5..=180.0 | -180.0..=-157.5 => Self::West,
299            -157.5..=-112.5 => Self::SouthWest,
300            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
301        }
302    }
303}
304
305impl Neg for CompassQuadrant {
306    type Output = CompassQuadrant;
307
308    fn neg(self) -> Self::Output {
309        self.opposite()
310    }
311}
312
313impl Neg for CompassOctant {
314    type Output = CompassOctant;
315
316    fn neg(self) -> Self::Output {
317        self.opposite()
318    }
319}
320
321#[cfg(test)]
322mod test_compass_quadrant {
323    use crate::{CompassQuadrant, Dir2, Vec2};
324
325    #[test]
326    fn test_cardinal_directions() {
327        let tests = [
328            (
329                Dir2::new(Vec2::new(1.0, 0.0)).unwrap(),
330                CompassQuadrant::East,
331            ),
332            (
333                Dir2::new(Vec2::new(0.0, 1.0)).unwrap(),
334                CompassQuadrant::North,
335            ),
336            (
337                Dir2::new(Vec2::new(-1.0, 0.0)).unwrap(),
338                CompassQuadrant::West,
339            ),
340            (
341                Dir2::new(Vec2::new(0.0, -1.0)).unwrap(),
342                CompassQuadrant::South,
343            ),
344        ];
345
346        for (dir, expected) in tests {
347            assert_eq!(CompassQuadrant::from(dir), expected);
348        }
349    }
350
351    #[test]
352    fn test_north_pie_slice() {
353        let tests = [
354            (
355                Dir2::new(Vec2::new(-0.1, 0.9)).unwrap(),
356                CompassQuadrant::North,
357            ),
358            (
359                Dir2::new(Vec2::new(0.1, 0.9)).unwrap(),
360                CompassQuadrant::North,
361            ),
362        ];
363
364        for (dir, expected) in tests {
365            assert_eq!(CompassQuadrant::from(dir), expected);
366        }
367    }
368
369    #[test]
370    fn test_east_pie_slice() {
371        let tests = [
372            (
373                Dir2::new(Vec2::new(0.9, 0.1)).unwrap(),
374                CompassQuadrant::East,
375            ),
376            (
377                Dir2::new(Vec2::new(0.9, -0.1)).unwrap(),
378                CompassQuadrant::East,
379            ),
380        ];
381
382        for (dir, expected) in tests {
383            assert_eq!(CompassQuadrant::from(dir), expected);
384        }
385    }
386
387    #[test]
388    fn test_south_pie_slice() {
389        let tests = [
390            (
391                Dir2::new(Vec2::new(-0.1, -0.9)).unwrap(),
392                CompassQuadrant::South,
393            ),
394            (
395                Dir2::new(Vec2::new(0.1, -0.9)).unwrap(),
396                CompassQuadrant::South,
397            ),
398        ];
399
400        for (dir, expected) in tests {
401            assert_eq!(CompassQuadrant::from(dir), expected);
402        }
403    }
404
405    #[test]
406    fn test_west_pie_slice() {
407        let tests = [
408            (
409                Dir2::new(Vec2::new(-0.9, -0.1)).unwrap(),
410                CompassQuadrant::West,
411            ),
412            (
413                Dir2::new(Vec2::new(-0.9, 0.1)).unwrap(),
414                CompassQuadrant::West,
415            ),
416        ];
417
418        for (dir, expected) in tests {
419            assert_eq!(CompassQuadrant::from(dir), expected);
420        }
421    }
422
423    #[test]
424    fn out_of_bounds_indexes_return_none() {
425        assert_eq!(CompassQuadrant::from_index(4), None);
426        assert_eq!(CompassQuadrant::from_index(5), None);
427        assert_eq!(CompassQuadrant::from_index(usize::MAX), None);
428    }
429
430    #[test]
431    fn compass_indexes_are_reversible() {
432        for i in 0..4 {
433            let quadrant = CompassQuadrant::from_index(i).unwrap();
434            assert_eq!(quadrant.to_index(), i);
435        }
436    }
437
438    #[test]
439    fn opposite_directions_reverse_themselves() {
440        for i in 0..4 {
441            let quadrant = CompassQuadrant::from_index(i).unwrap();
442            assert_eq!(-(-quadrant), quadrant);
443        }
444    }
445}
446
447#[cfg(test)]
448mod test_compass_octant {
449    use crate::{CompassOctant, Dir2, Vec2};
450
451    #[test]
452    fn test_cardinal_directions() {
453        let tests = [
454            (
455                Dir2::new(Vec2::new(-0.5, 0.5)).unwrap(),
456                CompassOctant::NorthWest,
457            ),
458            (
459                Dir2::new(Vec2::new(0.0, 1.0)).unwrap(),
460                CompassOctant::North,
461            ),
462            (
463                Dir2::new(Vec2::new(0.5, 0.5)).unwrap(),
464                CompassOctant::NorthEast,
465            ),
466            (Dir2::new(Vec2::new(1.0, 0.0)).unwrap(), CompassOctant::East),
467            (
468                Dir2::new(Vec2::new(0.5, -0.5)).unwrap(),
469                CompassOctant::SouthEast,
470            ),
471            (
472                Dir2::new(Vec2::new(0.0, -1.0)).unwrap(),
473                CompassOctant::South,
474            ),
475            (
476                Dir2::new(Vec2::new(-0.5, -0.5)).unwrap(),
477                CompassOctant::SouthWest,
478            ),
479            (
480                Dir2::new(Vec2::new(-1.0, 0.0)).unwrap(),
481                CompassOctant::West,
482            ),
483        ];
484
485        for (dir, expected) in tests {
486            assert_eq!(CompassOctant::from(dir), expected);
487        }
488    }
489
490    #[test]
491    fn test_north_pie_slice() {
492        let tests = [
493            (
494                Dir2::new(Vec2::new(-0.1, 0.9)).unwrap(),
495                CompassOctant::North,
496            ),
497            (
498                Dir2::new(Vec2::new(0.1, 0.9)).unwrap(),
499                CompassOctant::North,
500            ),
501        ];
502
503        for (dir, expected) in tests {
504            assert_eq!(CompassOctant::from(dir), expected);
505        }
506    }
507
508    #[test]
509    fn test_north_east_pie_slice() {
510        let tests = [
511            (
512                Dir2::new(Vec2::new(0.4, 0.6)).unwrap(),
513                CompassOctant::NorthEast,
514            ),
515            (
516                Dir2::new(Vec2::new(0.6, 0.4)).unwrap(),
517                CompassOctant::NorthEast,
518            ),
519        ];
520
521        for (dir, expected) in tests {
522            assert_eq!(CompassOctant::from(dir), expected);
523        }
524    }
525
526    #[test]
527    fn test_east_pie_slice() {
528        let tests = [
529            (Dir2::new(Vec2::new(0.9, 0.1)).unwrap(), CompassOctant::East),
530            (
531                Dir2::new(Vec2::new(0.9, -0.1)).unwrap(),
532                CompassOctant::East,
533            ),
534        ];
535
536        for (dir, expected) in tests {
537            assert_eq!(CompassOctant::from(dir), expected);
538        }
539    }
540
541    #[test]
542    fn test_south_east_pie_slice() {
543        let tests = [
544            (
545                Dir2::new(Vec2::new(0.4, -0.6)).unwrap(),
546                CompassOctant::SouthEast,
547            ),
548            (
549                Dir2::new(Vec2::new(0.6, -0.4)).unwrap(),
550                CompassOctant::SouthEast,
551            ),
552        ];
553
554        for (dir, expected) in tests {
555            assert_eq!(CompassOctant::from(dir), expected);
556        }
557    }
558
559    #[test]
560    fn test_south_pie_slice() {
561        let tests = [
562            (
563                Dir2::new(Vec2::new(-0.1, -0.9)).unwrap(),
564                CompassOctant::South,
565            ),
566            (
567                Dir2::new(Vec2::new(0.1, -0.9)).unwrap(),
568                CompassOctant::South,
569            ),
570        ];
571
572        for (dir, expected) in tests {
573            assert_eq!(CompassOctant::from(dir), expected);
574        }
575    }
576
577    #[test]
578    fn test_south_west_pie_slice() {
579        let tests = [
580            (
581                Dir2::new(Vec2::new(-0.4, -0.6)).unwrap(),
582                CompassOctant::SouthWest,
583            ),
584            (
585                Dir2::new(Vec2::new(-0.6, -0.4)).unwrap(),
586                CompassOctant::SouthWest,
587            ),
588        ];
589
590        for (dir, expected) in tests {
591            assert_eq!(CompassOctant::from(dir), expected);
592        }
593    }
594
595    #[test]
596    fn test_west_pie_slice() {
597        let tests = [
598            (
599                Dir2::new(Vec2::new(-0.9, -0.1)).unwrap(),
600                CompassOctant::West,
601            ),
602            (
603                Dir2::new(Vec2::new(-0.9, 0.1)).unwrap(),
604                CompassOctant::West,
605            ),
606        ];
607
608        for (dir, expected) in tests {
609            assert_eq!(CompassOctant::from(dir), expected);
610        }
611    }
612
613    #[test]
614    fn test_north_west_pie_slice() {
615        let tests = [
616            (
617                Dir2::new(Vec2::new(-0.4, 0.6)).unwrap(),
618                CompassOctant::NorthWest,
619            ),
620            (
621                Dir2::new(Vec2::new(-0.6, 0.4)).unwrap(),
622                CompassOctant::NorthWest,
623            ),
624        ];
625
626        for (dir, expected) in tests {
627            assert_eq!(CompassOctant::from(dir), expected);
628        }
629    }
630
631    #[test]
632    fn out_of_bounds_indexes_return_none() {
633        assert_eq!(CompassOctant::from_index(8), None);
634        assert_eq!(CompassOctant::from_index(9), None);
635        assert_eq!(CompassOctant::from_index(usize::MAX), None);
636    }
637
638    #[test]
639    fn compass_indexes_are_reversible() {
640        for i in 0..8 {
641            let octant = CompassOctant::from_index(i).unwrap();
642            assert_eq!(octant.to_index(), i);
643        }
644    }
645
646    #[test]
647    fn opposite_directions_reverse_themselves() {
648        for i in 0..8 {
649            let octant = CompassOctant::from_index(i).unwrap();
650            assert_eq!(-(-octant), octant);
651        }
652    }
653}