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:: vectors:: Vector2Axis ;
14- use crate :: builtin:: { real, RAffine2 , RVec2 , Vector2i } ;
14+ use crate :: builtin:: { inner , real, RAffine2 , RVec2 , Vector2i } ;
1515
1616use std:: fmt;
1717
@@ -36,172 +36,100 @@ pub struct Vector2 {
3636 pub y : real ,
3737}
3838
39- impl Vector2 {
40- /// Vector with all components set to `0.0`.
41- pub const ZERO : Self = Self :: splat ( 0.0 ) ;
42-
43- /// Vector with all components set to `1.0`.
44- pub const ONE : Self = Self :: splat ( 1.0 ) ;
45-
46- /// Vector with all components set to `real::INFINITY`.
47- pub const INF : Self = Self :: splat ( real:: INFINITY ) ;
48-
49- /// Unit vector in -X direction (right in 2D coordinate system).
50- pub const LEFT : Self = Self :: new ( -1.0 , 0.0 ) ;
51-
52- /// Unit vector in +X direction (right in 2D coordinate system).
53- pub const RIGHT : Self = Self :: new ( 1.0 , 0.0 ) ;
54-
55- /// Unit vector in -Y direction (up in 2D coordinate system).
56- pub const UP : Self = Self :: new ( 0.0 , -1.0 ) ;
39+ impl_vector_operators ! ( Vector2 , real, ( x, y) ) ;
5740
58- /// Unit vector in +Y direction (down in 2D coordinate system).
59- pub const DOWN : Self = Self :: new ( 0.0 , 1.0 ) ;
41+ impl_vector_consts ! ( Vector2 , real) ;
42+ impl_float_vector_consts ! ( Vector2 ) ;
43+ impl_vector2x_consts ! ( Vector2 , real) ;
6044
61- /// Constructs a new `Vector2` from the given `x` and `y`.
62- pub const fn new ( x : real , y : real ) -> Self {
63- Self { x, y }
64- }
65-
66- /// Constructs a new `Vector2` with both components set to `v`.
67- pub const fn splat ( v : real ) -> Self {
68- Self :: new ( v, v)
69- }
45+ impl_vector_fns ! ( Vector2 , RVec2 , real, ( x, y) ) ;
46+ impl_float_vector_fns ! ( Vector2 , ( x, y) ) ;
47+ impl_vector2x_fns ! ( Vector2 , real) ;
48+ impl_vector2_vector3_fns ! ( Vector2 , ( x, y) ) ;
7049
50+ impl Vector2 {
7151 /// Constructs a new `Vector2` from a [`Vector2i`].
52+ #[ inline]
7253 pub const fn from_vector2i ( v : Vector2i ) -> Self {
7354 Self {
7455 x : v. x as real ,
7556 y : v. y as real ,
7657 }
7758 }
7859
79- /// Converts the corresponding `glam` type to `Self`.
80- fn from_glam ( v : RVec2 ) -> Self {
81- Self :: new ( v. x , v. y )
82- }
83-
84- /// Converts `self` to the corresponding `glam` type.
85- fn to_glam ( self ) -> RVec2 {
86- RVec2 :: new ( self . x , self . y )
60+ #[ doc( hidden) ]
61+ #[ inline]
62+ pub fn as_inner ( & self ) -> inner:: InnerVector2 {
63+ inner:: InnerVector2 :: from_outer ( self )
8764 }
8865
66+ /// Returns this vector's angle with respect to the positive X axis, or `(1.0, 0.0)` vector, in radians.
67+ ///
68+ /// For example, `Vector2::RIGHT.angle()` will return zero, `Vector2::DOWN.angle()` will return `PI / 2` (a quarter turn, or 90 degrees),
69+ /// and `Vector2::new(1.0, -1.0).angle()` will return `-PI / 4` (a negative eighth turn, or -45 degrees).
70+ ///
71+ /// [Illustration of the returned angle.](https://raw.githubusercontent.com/godotengine/godot-docs/master/img/vector2_angle.png)
72+ ///
73+ /// Equivalent to the result of `y.atan2(x)`.
74+ #[ inline]
8975 pub fn angle ( self ) -> real {
9076 self . y . atan2 ( self . x )
9177 }
9278
93- pub fn angle_to ( self , to : Self ) -> real {
94- self . to_glam ( ) . angle_between ( to . to_glam ( ) )
95- }
96-
79+ /// Returns the angle to the given vector, in radians.
80+ ///
81+ /// [Illustration of the returned angle.](https://raw.githubusercontent.com/godotengine/godot-docs/master/img/vector2_angle_to.png)
82+ # [ inline ]
9783 pub fn angle_to_point ( self , to : Self ) -> real {
9884 ( to - self ) . angle ( )
9985 }
10086
101- pub fn aspect ( self ) -> real {
102- self . x / self . y
103- }
104-
105- pub fn bounce ( self , normal : Self ) -> Self {
106- -self . reflect ( normal)
107- }
108-
109- pub fn ceil ( self ) -> Self {
110- Self :: from_glam ( self . to_glam ( ) . ceil ( ) )
111- }
112-
113- pub fn clamp ( self , min : Self , max : Self ) -> Self {
114- Self :: from_glam ( self . to_glam ( ) . clamp ( min. to_glam ( ) , max. to_glam ( ) ) )
115- }
116-
87+ /// Returns the 2D analog of the cross product for this vector and `with`.
88+ ///
89+ /// This is the signed area of the parallelogram formed by the two vectors. If the second vector is clockwise from the first vector,
90+ /// then the cross product is the positive area. If counter-clockwise, the cross product is the negative area. If the two vectors are
91+ /// parallel this returns zero, making it useful for testing if two vectors are parallel.
92+ ///
93+ /// Note: Cross product is not defined in 2D mathematically. This method embeds the 2D vectors in the XY plane of 3D space and uses
94+ /// their cross product's Z component as the analog.
95+ #[ inline]
11796 pub fn cross ( self , with : Self ) -> real {
11897 self . to_glam ( ) . perp_dot ( with. to_glam ( ) )
11998 }
12099
121- pub fn direction_to ( self , to : Self ) -> Self {
122- ( to - self ) . normalized ( )
123- }
124-
125- pub fn distance_squared_to ( self , to : Self ) -> real {
126- ( to - self ) . length_squared ( )
127- }
128-
129- pub fn distance_to ( self , to : Self ) -> real {
130- ( to - self ) . length ( )
131- }
132-
133- pub fn dot ( self , other : Self ) -> real {
134- self . to_glam ( ) . dot ( other. to_glam ( ) )
135- }
136-
137- pub fn floor ( self ) -> Self {
138- Self :: from_glam ( self . to_glam ( ) . floor ( ) )
139- }
140-
100+ /// Creates a unit Vector2 rotated to the given `angle` in radians. This is equivalent to doing `Vector2::new(angle.cos(), angle.sin())`
101+ /// or `Vector2::RIGHT.rotated(angle)`.
102+ ///
103+ /// ```no_run
104+ /// use godot::prelude::*;
105+ ///
106+ /// let a = Vector2::from_angle(0.0); // (1.0, 0.0)
107+ /// let b = Vector2::new(1.0, 0.0).angle(); // 0.0
108+ /// let c = Vector2::from_angle(real_consts::PI / 2.0); // (0.0, 1.0)
109+ /// ```
110+ #[ inline]
141111 pub fn from_angle ( angle : real ) -> Self {
142112 Self :: from_glam ( RVec2 :: from_angle ( angle) )
143113 }
144114
145- pub fn is_finite ( self ) -> bool {
146- self . to_glam ( ) . is_finite ( )
147- }
148-
149- pub fn is_normalized ( self ) -> bool {
150- self . to_glam ( ) . is_normalized ( )
151- }
152-
153- pub fn length_squared ( self ) -> real {
154- self . to_glam ( ) . length_squared ( )
155- }
156-
157- pub fn limit_length ( self , length : Option < real > ) -> Self {
158- Self :: from_glam ( self . to_glam ( ) . clamp_length_max ( length. unwrap_or ( 1.0 ) ) )
159- }
160-
161- pub fn max_axis_index ( self ) -> Vector2Axis {
162- if self . x < self . y {
163- Vector2Axis :: Y
164- } else {
165- Vector2Axis :: X
166- }
167- }
168-
169- pub fn min_axis_index ( self ) -> Vector2Axis {
170- if self . x < self . y {
171- Vector2Axis :: X
172- } else {
173- Vector2Axis :: Y
174- }
175- }
176-
177- pub fn move_toward ( self , to : Self , delta : real ) -> Self {
178- let vd = to - self ;
179- let len = vd. length ( ) ;
180- if len <= delta || len < real:: CMP_EPSILON {
181- to
182- } else {
183- self + vd / len * delta
184- }
185- }
186-
115+ /// Returns a perpendicular vector rotated 90 degrees counter-clockwise compared to the original, with the same length.
116+ #[ inline]
187117 pub fn orthogonal ( self ) -> Self {
188118 Self :: new ( self . y , -self . x )
189119 }
190120
191- pub fn project ( self , b : Self ) -> Self {
192- Self :: from_glam ( self . to_glam ( ) . project_onto ( b. to_glam ( ) ) )
193- }
194-
195- pub fn reflect ( self , normal : Self ) -> Self {
196- 2.0 * normal * self . dot ( normal) - self
197- }
198-
199- pub fn round ( self ) -> Self {
200- Self :: from_glam ( self . to_glam ( ) . round ( ) )
121+ /// Returns the result of rotating this vector by `angle` (in radians).
122+ #[ inline]
123+ pub fn rotated ( self , angle : real ) -> Self {
124+ Self :: from_glam ( RAffine2 :: from_angle ( angle) . transform_vector2 ( self . to_glam ( ) ) )
201125 }
202126
203- // TODO compare with gdnative implementation:
204- // https://github.com/godot-rust/gdnative/blob/master/gdnative-core/src/core_types/vector3.rs#L335-L343
127+ /// Returns the result of spherical linear interpolation between this vector and `to`, by amount `weight`.
128+ /// `weight` is on the range of 0.0 to 1.0, representing the amount of interpolation.
129+ ///
130+ /// This method also handles interpolating the lengths if the input vectors have different lengths.
131+ /// For the special case of one or both input vectors having zero length, this method behaves like [`Vector2::lerp`].
132+ #[ inline]
205133 pub fn slerp ( self , to : Self , weight : real ) -> Self {
206134 let start_length_sq = self . length_squared ( ) ;
207135 let end_length_sq = to. length_squared ( ) ;
@@ -213,24 +141,6 @@ impl Vector2 {
213141 let angle = self . angle_to ( to) ;
214142 self . rotated ( angle * weight) * ( result_length / start_length)
215143 }
216-
217- pub fn slide ( self , normal : Self ) -> Self {
218- self - normal * self . dot ( normal)
219- }
220-
221- /// Returns the result of rotating this vector by `angle` (in radians).
222- pub fn rotated ( self , angle : real ) -> Self {
223- Self :: from_glam ( RAffine2 :: from_angle ( angle) . transform_vector2 ( self . to_glam ( ) ) )
224- }
225-
226- #[ doc( hidden) ]
227- pub fn as_inner ( & self ) -> inner:: InnerVector2 {
228- inner:: InnerVector2 :: from_outer ( self )
229- }
230-
231- pub fn coords ( & self ) -> ( real , real ) {
232- ( self . x , self . y )
233- }
234144}
235145
236146/// Formats the vector like Godot: `(x, y)`.
@@ -240,12 +150,6 @@ impl fmt::Display for Vector2 {
240150 }
241151}
242152
243- impl_common_vector_fns ! ( Vector2 , real) ;
244- impl_float_vector_glam_fns ! ( Vector2 , real) ;
245- impl_float_vector_component_fns ! ( Vector2 , real, ( x, y) ) ;
246- impl_vector_operators ! ( Vector2 , real, ( x, y) ) ;
247- impl_swizzle_trait_for_vector2x ! ( Vector2 , real) ;
248-
249153// SAFETY:
250154// This type is represented as `Self` in Godot, so `*mut Self` is sound.
251155unsafe impl GodotFfi for Vector2 {
0 commit comments