55 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
66 */
77
8+ use core:: cmp:: Ordering ;
89use godot_ffi as sys;
910use sys:: { ffi_methods, GodotFfi } ;
1011
11- use crate :: builtin:: inner;
1212use crate :: builtin:: math:: { FloatExt , GlamConv , GlamType } ;
1313use crate :: builtin:: meta:: impl_godot_as_self;
1414use crate :: builtin:: vectors:: Vector2Axis ;
15- use crate :: builtin:: { real, RAffine2 , RVec2 , Vector2i } ;
15+ use crate :: builtin:: { inner , real, RAffine2 , RVec2 , Vector2i } ;
1616
1717use std:: fmt;
1818
@@ -37,172 +37,101 @@ pub struct Vector2 {
3737 pub y : real ,
3838}
3939
40- impl Vector2 {
41- /// Vector with all components set to `0.0`.
42- pub const ZERO : Self = Self :: splat ( 0.0 ) ;
43-
44- /// Vector with all components set to `1.0`.
45- pub const ONE : Self = Self :: splat ( 1.0 ) ;
46-
47- /// Vector with all components set to `real::INFINITY`.
48- pub const INF : Self = Self :: splat ( real:: INFINITY ) ;
49-
50- /// Unit vector in -X direction (right in 2D coordinate system).
51- pub const LEFT : Self = Self :: new ( -1.0 , 0.0 ) ;
52-
53- /// Unit vector in +X direction (right in 2D coordinate system).
54- pub const RIGHT : Self = Self :: new ( 1.0 , 0.0 ) ;
55-
56- /// Unit vector in -Y direction (up in 2D coordinate system).
57- pub const UP : Self = Self :: new ( 0.0 , -1.0 ) ;
40+ impl_vector_operators ! ( Vector2 , real, ( x, y) ) ;
5841
59- /// Unit vector in +Y direction (down in 2D coordinate system).
60- pub const DOWN : Self = Self :: new ( 0.0 , 1.0 ) ;
42+ impl_vector_consts ! ( Vector2 , real) ;
43+ impl_float_vector_consts ! ( Vector2 ) ;
44+ impl_vector2x_consts ! ( Vector2 , real) ;
6145
62- /// Constructs a new `Vector2` from the given `x` and `y`.
63- pub const fn new ( x : real , y : real ) -> Self {
64- Self { x, y }
65- }
66-
67- /// Constructs a new `Vector2` with both components set to `v`.
68- pub const fn splat ( v : real ) -> Self {
69- Self :: new ( v, v)
70- }
46+ impl_vector_fns ! ( Vector2 , RVec2 , real, ( x, y) ) ;
47+ impl_float_vector_fns ! ( Vector2 , ( x, y) ) ;
48+ impl_vector2x_fns ! ( Vector2 , real) ;
49+ impl_vector2_vector3_fns ! ( Vector2 , ( x, y) ) ;
7150
51+ impl Vector2 {
7252 /// Constructs a new `Vector2` from a [`Vector2i`].
53+ #[ inline]
7354 pub const fn from_vector2i ( v : Vector2i ) -> Self {
7455 Self {
7556 x : v. x as real ,
7657 y : v. y as real ,
7758 }
7859 }
7960
80- /// Converts the corresponding `glam` type to `Self`.
81- fn from_glam ( v : RVec2 ) -> Self {
82- Self :: new ( v. x , v. y )
83- }
84-
85- /// Converts `self` to the corresponding `glam` type.
86- fn to_glam ( self ) -> RVec2 {
87- RVec2 :: new ( self . x , self . y )
61+ #[ doc( hidden) ]
62+ #[ inline]
63+ pub fn as_inner ( & self ) -> inner:: InnerVector2 {
64+ inner:: InnerVector2 :: from_outer ( self )
8865 }
8966
67+ /// Returns this vector's angle with respect to the positive X axis, or `(1.0, 0.0)` vector, in radians.
68+ ///
69+ /// For example, `Vector2::RIGHT.angle()` will return zero, `Vector2::DOWN.angle()` will return `PI / 2` (a quarter turn, or 90 degrees),
70+ /// and `Vector2::new(1.0, -1.0).angle()` will return `-PI / 4` (a negative eighth turn, or -45 degrees).
71+ ///
72+ /// [Illustration of the returned angle.](https://raw.githubusercontent.com/godotengine/godot-docs/master/img/vector2_angle.png)
73+ ///
74+ /// Equivalent to the result of `y.atan2(x)`.
75+ #[ inline]
9076 pub fn angle ( self ) -> real {
9177 self . y . atan2 ( self . x )
9278 }
9379
94- pub fn angle_to ( self , to : Self ) -> real {
95- self . to_glam ( ) . angle_between ( to . to_glam ( ) )
96- }
97-
80+ /// Returns the angle to the given vector, in radians.
81+ ///
82+ /// [Illustration of the returned angle.](https://raw.githubusercontent.com/godotengine/godot-docs/master/img/vector2_angle_to.png)
83+ # [ inline ]
9884 pub fn angle_to_point ( self , to : Self ) -> real {
9985 ( to - self ) . angle ( )
10086 }
10187
102- pub fn aspect ( self ) -> real {
103- self . x / self . y
104- }
105-
106- pub fn bounce ( self , normal : Self ) -> Self {
107- -self . reflect ( normal)
108- }
109-
110- pub fn ceil ( self ) -> Self {
111- Self :: from_glam ( self . to_glam ( ) . ceil ( ) )
112- }
113-
114- pub fn clamp ( self , min : Self , max : Self ) -> Self {
115- Self :: from_glam ( self . to_glam ( ) . clamp ( min. to_glam ( ) , max. to_glam ( ) ) )
116- }
117-
88+ /// Returns the 2D analog of the cross product for this vector and `with`.
89+ ///
90+ /// This is the signed area of the parallelogram formed by the two vectors. If the second vector is clockwise from the first vector,
91+ /// then the cross product is the positive area. If counter-clockwise, the cross product is the negative area. If the two vectors are
92+ /// parallel this returns zero, making it useful for testing if two vectors are parallel.
93+ ///
94+ /// Note: Cross product is not defined in 2D mathematically. This method embeds the 2D vectors in the XY plane of 3D space and uses
95+ /// their cross product's Z component as the analog.
96+ #[ inline]
11897 pub fn cross ( self , with : Self ) -> real {
11998 self . to_glam ( ) . perp_dot ( with. to_glam ( ) )
12099 }
121100
122- pub fn direction_to ( self , to : Self ) -> Self {
123- ( to - self ) . normalized ( )
124- }
125-
126- pub fn distance_squared_to ( self , to : Self ) -> real {
127- ( to - self ) . length_squared ( )
128- }
129-
130- pub fn distance_to ( self , to : Self ) -> real {
131- ( to - self ) . length ( )
132- }
133-
134- pub fn dot ( self , other : Self ) -> real {
135- self . to_glam ( ) . dot ( other. to_glam ( ) )
136- }
137-
138- pub fn floor ( self ) -> Self {
139- Self :: from_glam ( self . to_glam ( ) . floor ( ) )
140- }
141-
101+ /// Creates a unit Vector2 rotated to the given `angle` in radians. This is equivalent to doing `Vector2::new(angle.cos(), angle.sin())`
102+ /// or `Vector2::RIGHT.rotated(angle)`.
103+ ///
104+ /// ```no_run
105+ /// use godot::prelude::*;
106+ /// use std::f32::consts::PI;
107+ ///
108+ /// let a = Vector2::from_angle(0.0); // (1.0, 0.0)
109+ /// let b = Vector2::new(1.0, 0.0).angle(); // 0.0
110+ /// let c = Vector2::from_angle(PI / 2.0); // (0.0, 1.0)
111+ /// ```
112+ #[ inline]
142113 pub fn from_angle ( angle : real ) -> Self {
143114 Self :: from_glam ( RVec2 :: from_angle ( angle) )
144115 }
145116
146- pub fn is_finite ( self ) -> bool {
147- self . to_glam ( ) . is_finite ( )
148- }
149-
150- pub fn is_normalized ( self ) -> bool {
151- self . to_glam ( ) . is_normalized ( )
152- }
153-
154- pub fn length_squared ( self ) -> real {
155- self . to_glam ( ) . length_squared ( )
156- }
157-
158- pub fn limit_length ( self , length : Option < real > ) -> Self {
159- Self :: from_glam ( self . to_glam ( ) . clamp_length_max ( length. unwrap_or ( 1.0 ) ) )
160- }
161-
162- pub fn max_axis_index ( self ) -> Vector2Axis {
163- if self . x < self . y {
164- Vector2Axis :: Y
165- } else {
166- Vector2Axis :: X
167- }
168- }
169-
170- pub fn min_axis_index ( self ) -> Vector2Axis {
171- if self . x < self . y {
172- Vector2Axis :: X
173- } else {
174- Vector2Axis :: Y
175- }
176- }
177-
178- pub fn move_toward ( self , to : Self , delta : real ) -> Self {
179- let vd = to - self ;
180- let len = vd. length ( ) ;
181- if len <= delta || len < real:: CMP_EPSILON {
182- to
183- } else {
184- self + vd / len * delta
185- }
186- }
187-
117+ /// Returns a perpendicular vector rotated 90 degrees counter-clockwise compared to the original, with the same length.
118+ #[ inline]
188119 pub fn orthogonal ( self ) -> Self {
189120 Self :: new ( self . y , -self . x )
190121 }
191122
192- pub fn project ( self , b : Self ) -> Self {
193- Self :: from_glam ( self . to_glam ( ) . project_onto ( b. to_glam ( ) ) )
194- }
195-
196- pub fn reflect ( self , normal : Self ) -> Self {
197- 2.0 * normal * self . dot ( normal) - self
198- }
199-
200- pub fn round ( self ) -> Self {
201- Self :: from_glam ( self . to_glam ( ) . round ( ) )
123+ /// Returns the result of rotating this vector by `angle` (in radians).
124+ #[ inline]
125+ pub fn rotated ( self , angle : real ) -> Self {
126+ Self :: from_glam ( RAffine2 :: from_angle ( angle) . transform_vector2 ( self . to_glam ( ) ) )
202127 }
203128
204- // TODO compare with gdnative implementation:
205- // https://github.com/godot-rust/gdnative/blob/master/gdnative-core/src/core_types/vector3.rs#L335-L343
129+ /// Returns the result of spherical linear interpolation between this vector and `to`, by amount `weight`.
130+ /// `weight` is on the range of 0.0 to 1.0, representing the amount of interpolation.
131+ ///
132+ /// This method also handles interpolating the lengths if the input vectors have different lengths.
133+ /// For the special case of one or both input vectors having zero length, this method behaves like [`Vector2::lerp`].
134+ #[ inline]
206135 pub fn slerp ( self , to : Self , weight : real ) -> Self {
207136 let start_length_sq = self . length_squared ( ) ;
208137 let end_length_sq = to. length_squared ( ) ;
@@ -214,24 +143,6 @@ impl Vector2 {
214143 let angle = self . angle_to ( to) ;
215144 self . rotated ( angle * weight) * ( result_length / start_length)
216145 }
217-
218- pub fn slide ( self , normal : Self ) -> Self {
219- self - normal * self . dot ( normal)
220- }
221-
222- /// Returns the result of rotating this vector by `angle` (in radians).
223- pub fn rotated ( self , angle : real ) -> Self {
224- Self :: from_glam ( RAffine2 :: from_angle ( angle) . transform_vector2 ( self . to_glam ( ) ) )
225- }
226-
227- #[ doc( hidden) ]
228- pub fn as_inner ( & self ) -> inner:: InnerVector2 {
229- inner:: InnerVector2 :: from_outer ( self )
230- }
231-
232- pub fn coords ( & self ) -> ( real , real ) {
233- ( self . x , self . y )
234- }
235146}
236147
237148/// Formats the vector like Godot: `(x, y)`.
@@ -241,12 +152,6 @@ impl fmt::Display for Vector2 {
241152 }
242153}
243154
244- impl_common_vector_fns ! ( Vector2 , real) ;
245- impl_float_vector_glam_fns ! ( Vector2 , real) ;
246- impl_float_vector_component_fns ! ( Vector2 , real, ( x, y) ) ;
247- impl_vector_operators ! ( Vector2 , real, ( x, y) ) ;
248- impl_swizzle_trait_for_vector2x ! ( Vector2 , real) ;
249-
250155// SAFETY:
251156// This type is represented as `Self` in Godot, so `*mut Self` is sound.
252157unsafe impl GodotFfi for Vector2 {
0 commit comments