32 #include "math_funcs.h" 77 _FORCE_INLINE_
float& operator[](
int p_idx) {
80 _FORCE_INLINE_
const float& operator[](
int p_idx)
const {
88 float length_squared()
const;
90 float distance_to(
const Vector2& p_vector2)
const;
91 float distance_squared_to(
const Vector2& p_vector2)
const;
92 float angle_to(
const Vector2& p_vector2)
const;
93 float angle_to_point(
const Vector2& p_vector2)
const;
95 float dot(
const Vector2& p_other)
const;
96 float cross(
const Vector2& p_other)
const;
97 Vector2 cross(real_t p_other)
const;
102 Vector2 clamped(real_t p_len)
const;
105 _FORCE_INLINE_
Vector2 linear_interpolate(
const Vector2& p_b,
float p_t)
const;
113 void operator+=(
const Vector2& p_v);
115 void operator-=(
const Vector2& p_v);
118 Vector2 operator*(
const float &rvalue)
const;
119 void operator*=(
const float &rvalue);
120 void operator*=(
const Vector2 &rvalue) { *
this = *
this * rvalue; }
124 Vector2 operator/(
const float &rvalue)
const;
126 void operator/=(
const float &rvalue);
130 bool operator==(
const Vector2& p_vec2)
const;
131 bool operator!=(
const Vector2& p_vec2)
const;
133 bool operator<(
const Vector2& p_vec2)
const {
return (x==p_vec2.x)?(y<p_vec2.y):(x<p_vec2.x); }
134 bool operator<=(
const Vector2& p_vec2)
const {
return (x==p_vec2.x)?(y<=p_vec2.y):(x<=p_vec2.x); }
136 real_t angle()
const;
138 void set_rotation(
float p_radians) {
140 x=Math::sin(p_radians);
141 y=Math::cos(p_radians);
144 _FORCE_INLINE_
Vector2 abs()
const {
146 return Vector2( Math::abs(x), Math::abs(y) );
149 Vector2 rotated(
float p_by)
const;
157 float get_aspect()
const {
return width/height; }
160 operator String()
const {
return String::num(x)+
","+String::num(y); }
162 _FORCE_INLINE_
Vector2(
float p_x,
float p_y) { x=p_x; y=p_y; }
163 _FORCE_INLINE_
Vector2() { x=0; y=0; }
166 _FORCE_INLINE_
Vector2 Vector2::plane_project(real_t p_d,
const Vector2& p_vec)
const {
168 return p_vec - *
this * ( dot(p_vec) -p_d);
172 _FORCE_INLINE_
Vector2 operator*(
float p_scalar,
const Vector2& p_vec) {
174 return p_vec*p_scalar;
177 Vector2 Vector2::linear_interpolate(
const Vector2& p_b,
float p_t)
const {
181 res.x+= (p_t * (p_b.x-x));
182 res.y+= (p_t * (p_b.y-y));
192 res.x+= (p_t * (p_b.x-p_a.x));
193 res.y+= (p_t * (p_b.y-p_a.y));
209 const Vector2& get_pos()
const {
return pos; }
210 void set_pos(
const Vector2& p_pos) { pos=p_pos; }
211 const Vector2& get_size()
const {
return size; }
212 void set_size(
const Vector2& p_size) { size=p_size; }
214 float get_area()
const {
return size.width*size.height; }
216 inline bool intersects(
const Rect2& p_rect)
const {
217 if ( pos.x >= (p_rect.pos.x + p_rect.size.width) )
219 if ( (pos.x+size.width) <= p_rect.pos.x )
221 if ( pos.y >= (p_rect.pos.y + p_rect.size.height) )
223 if ( (pos.y+size.height) <= p_rect.pos.y )
229 inline float distance_to(
const Vector2& p_point)
const {
233 if (p_point.x < pos.x) {
234 dist=MIN(dist,pos.x-p_point.x);
236 if (p_point.y < pos.y) {
237 dist=MIN(dist,pos.y-p_point.y);
239 if (p_point.x >= (pos.x+size.x) ) {
240 dist=MIN(p_point.x-(pos.x+size.x),dist);
242 if (p_point.y >= (pos.y+size.y) ) {
243 dist=MIN(p_point.y-(pos.y+size.y),dist);
252 _FORCE_INLINE_
bool intersects_transformed(
const Matrix32& p_xform,
const Rect2& p_rect)
const;
256 inline bool encloses(
const Rect2& p_rect)
const {
258 return (p_rect.pos.x>=pos.x) && (p_rect.pos.y>=pos.y) &&
259 ((p_rect.pos.x+p_rect.size.x)<(pos.x+size.x)) &&
260 ((p_rect.pos.y+p_rect.size.y)<(pos.y+size.y));
264 inline bool has_no_area()
const {
266 return (size.x<=0 || size.y<=0);
271 Rect2 new_rect=p_rect;
273 if (!intersects( new_rect ))
276 new_rect.pos.x = MAX( p_rect.pos.x , pos.x );
277 new_rect.pos.y = MAX( p_rect.pos.y , pos.y );
279 Point2 p_rect_end=p_rect.pos+p_rect.size;
282 new_rect.size.x=MIN(p_rect_end.x,end.x) - new_rect.pos.x;
283 new_rect.size.y=MIN(p_rect_end.y,end.y) - new_rect.pos.y;
292 new_rect.pos.x=MIN( p_rect.pos.x , pos.x );
293 new_rect.pos.y=MIN( p_rect.pos.y , pos.y );
296 new_rect.size.x = MAX( p_rect.pos.x+p_rect.size.x , pos.x+size.x );
297 new_rect.size.y = MAX( p_rect.pos.y+p_rect.size.y , pos.y+size.y );
299 new_rect.size = new_rect.size - new_rect.pos;
303 inline bool has_point(
const Point2& p_point)
const {
304 if (p_point.x < pos.x)
306 if (p_point.y < pos.y)
309 if (p_point.x >= (pos.x+size.x) )
311 if (p_point.y >= (pos.y+size.y) )
317 inline bool no_area()
const {
return (size.width<=0 || size.height<=0 ); }
319 bool operator==(
const Rect2& p_rect)
const {
return pos==p_rect.pos && size==p_rect.size; }
320 bool operator!=(
const Rect2& p_rect)
const {
return pos!=p_rect.pos || size!=p_rect.size; }
322 inline Rect2 grow(real_t p_by)
const {
327 g.size.width+=p_by*2;
328 g.size.height+=p_by*2;
335 r.expand_to(p_vector);
339 inline void expand_to(
const Vector2& p_vector) {
344 if (p_vector.x<begin.x)
346 if (p_vector.y<begin.y)
349 if (p_vector.x>end.x)
351 if (p_vector.y>end.y)
362 Rect2(
float p_x,
float p_y,
float p_width,
float p_height) { pos=
Point2(p_x,p_y); size=
Size2( p_width, p_height ); }
363 Rect2(
const Point2& p_pos,
const Size2& p_size ) { pos=p_pos; size=p_size; }
381 _FORCE_INLINE_
int& operator[](
int p_idx) {
384 _FORCE_INLINE_
const int& operator[](
int p_idx)
const {
389 void operator+=(
const Point2i& p_v);
391 void operator-=(
const Point2i& p_v);
394 Point2i operator*(
const int &rvalue)
const;
395 void operator*=(
const int &rvalue);
399 Point2i operator/(
const int &rvalue)
const;
401 void operator/=(
const int &rvalue);
404 bool operator<(
const Point2i& p_vec2)
const {
return (x==p_vec2.x)?(y<p_vec2.y):(x<p_vec2.x); }
405 bool operator>(
const Point2i& p_vec2)
const {
return (x==p_vec2.x)?(y>p_vec2.y):(x>p_vec2.x); }
407 bool operator==(
const Point2i& p_vec2)
const;
408 bool operator!=(
const Point2i& p_vec2)
const;
410 float get_aspect()
const {
return width/(float)height; }
412 operator String()
const {
return String::num(x)+
","+String::num(y); }
415 inline Point2i(
const Vector2& p_vec2) { x=(int)p_vec2.x; y=(
int)p_vec2.y; }
416 inline Point2i(
int p_x,
int p_y) { x=p_x; y=p_y; }
427 const Point2i& get_pos()
const {
return pos; }
428 void set_pos(
const Point2i& p_pos) { pos=p_pos; }
429 const Point2i& get_size()
const {
return size; }
430 void set_size(
const Point2i& p_size) { size=p_size; }
432 int get_area()
const {
return size.width*size.height; }
434 inline bool intersects(
const Rect2i& p_rect)
const {
435 if ( pos.x > (p_rect.pos.x + p_rect.size.width) )
437 if ( (pos.x+size.width) < p_rect.pos.x )
439 if ( pos.y > (p_rect.pos.y + p_rect.size.height) )
441 if ( (pos.y+size.height) < p_rect.pos.y )
447 inline bool encloses(
const Rect2i& p_rect)
const {
449 return (p_rect.pos.x>=pos.x) && (p_rect.pos.y>=pos.y) &&
450 ((p_rect.pos.x+p_rect.size.x)<(pos.x+size.x)) &&
451 ((p_rect.pos.y+p_rect.size.y)<(pos.y+size.y));
455 inline bool has_no_area()
const {
457 return (size.x<=0 || size.y<=0);
464 if (!intersects( new_rect ))
467 new_rect.pos.x = MAX( p_rect.pos.x , pos.x );
468 new_rect.pos.y = MAX( p_rect.pos.y , pos.y );
470 Point2 p_rect_end=p_rect.pos+p_rect.size;
473 new_rect.size.x=(int)(MIN(p_rect_end.x,end.x) - new_rect.pos.x);
474 new_rect.size.y=(int)(MIN(p_rect_end.y,end.y) - new_rect.pos.y);
483 new_rect.pos.x=MIN( p_rect.pos.x , pos.x );
484 new_rect.pos.y=MIN( p_rect.pos.y , pos.y );
487 new_rect.size.x = MAX( p_rect.pos.x+p_rect.size.x , pos.x+size.x );
488 new_rect.size.y = MAX( p_rect.pos.y+p_rect.size.y , pos.y+size.y );
490 new_rect.size = new_rect.size - new_rect.pos;
494 bool has_point(
const Point2& p_point)
const {
495 if (p_point.x < pos.x)
497 if (p_point.y < pos.y)
500 if (p_point.x >= (pos.x+size.x) )
502 if (p_point.y >= (pos.y+size.y) )
508 bool no_area() {
return (size.width<=0 || size.height<=0 ); }
510 bool operator==(
const Rect2i& p_rect)
const {
return pos==p_rect.pos && size==p_rect.size; }
511 bool operator!=(
const Rect2i& p_rect)
const {
return pos!=p_rect.pos || size!=p_rect.size; }
513 Rect2i grow(
int p_by)
const {
518 g.size.width+=p_by*2;
519 g.size.height+=p_by*2;
523 inline void expand_to(
const Point2i& p_vector) {
528 if (p_vector.x<begin.x)
530 if (p_vector.y<begin.y)
533 if (p_vector.x>end.x)
535 if (p_vector.y>end.y)
545 operator Rect2()
const {
return Rect2(pos,size); }
546 Rect2i(
const Rect2& p_r2) { pos=p_r2.pos; size=p_r2.size; }
548 Rect2i(
int p_x,
int p_y,
int p_width,
int p_height) { pos=
Point2(p_x,p_y); size=
Size2( p_width, p_height ); }
560 _FORCE_INLINE_
float tdotx(
const Vector2& v)
const {
return elements[0][0] * v.x + elements[1][0] * v.y; }
561 _FORCE_INLINE_
float tdoty(
const Vector2& v)
const {
return elements[0][1] * v.x + elements[1][1] * v.y; }
563 const Vector2& operator[](
int p_idx)
const {
return elements[p_idx]; }
564 Vector2& operator[](
int p_idx) {
return elements[p_idx]; }
566 _FORCE_INLINE_
Vector2 get_axis(
int p_axis)
const { ERR_FAIL_INDEX_V(p_axis,3,
Vector2());
return elements[p_axis]; }
567 _FORCE_INLINE_
void set_axis(
int p_axis,
const Vector2& p_vec) { ERR_FAIL_INDEX(p_axis,3); elements[p_axis]=p_vec; }
572 void affine_invert();
575 void set_rotation(real_t p_phi);
576 real_t get_rotation()
const;
577 _FORCE_INLINE_
void set_rotation_and_scale(real_t p_phi,
const Size2& p_scale);
578 void rotate(real_t p_phi);
580 void scale(
const Vector2& p_scale);
581 void scale_basis(
const Vector2& p_scale);
582 void translate( real_t p_tx, real_t p_ty);
583 void translate(
const Vector2& p_translation );
585 float basis_determinant()
const;
589 _FORCE_INLINE_
const Vector2& get_origin()
const {
return elements[2]; }
590 _FORCE_INLINE_
void set_origin(
const Vector2& p_origin) { elements[2]=p_origin; }
595 Matrix32 rotated(
float p_phi)
const;
600 void orthonormalize();
603 bool operator==(
const Matrix32& p_transform)
const;
604 bool operator!=(
const Matrix32& p_transform)
const;
606 void operator*=(
const Matrix32& p_transform);
612 _FORCE_INLINE_
Vector2 basis_xform_inv(
const Vector2& p_vec)
const;
615 _FORCE_INLINE_
Rect2 xform(
const Rect2& p_vec)
const;
616 _FORCE_INLINE_
Rect2 xform_inv(
const Rect2& p_vec)
const;
623 Matrix32() { elements[0][0]=1.0; elements[1][1]=1.0; }
627 bool Rect2::intersects_transformed(
const Matrix32& p_xform,
const Rect2& p_rect)
const {
632 p_xform.xform(p_rect.pos),
633 p_xform.xform(
Vector2(p_rect.pos.x+p_rect.size.x,p_rect.pos.y)),
634 p_xform.xform(
Vector2(p_rect.pos.x,p_rect.pos.y+p_rect.size.y)),
635 p_xform.xform(
Vector2(p_rect.pos.x+p_rect.size.x,p_rect.pos.y+p_rect.size.y)),
642 if (xf_points[0].y>pos.y)
644 if (xf_points[1].y>pos.y)
646 if (xf_points[2].y>pos.y)
648 if (xf_points[3].y>pos.y)
655 low_limit=pos.y+size.y;
657 if (xf_points[0].y<low_limit)
659 if (xf_points[1].y<low_limit)
661 if (xf_points[2].y<low_limit)
663 if (xf_points[3].y<low_limit)
670 if (xf_points[0].x>pos.x)
672 if (xf_points[1].x>pos.x)
674 if (xf_points[2].x>pos.x)
676 if (xf_points[3].x>pos.x)
683 low_limit=pos.x+size.x;
685 if (xf_points[0].x<low_limit)
687 if (xf_points[1].x<low_limit)
689 if (xf_points[2].x<low_limit)
691 if (xf_points[3].x<low_limit)
702 Vector2(pos.x+size.x,pos.y+size.y),
705 real_t maxa=p_xform.elements[0].dot(xf_points2[0]);
708 real_t dp = p_xform.elements[0].dot(xf_points2[1]);
712 dp = p_xform.elements[0].dot(xf_points2[2]);
716 dp = p_xform.elements[0].dot(xf_points2[3]);
720 real_t maxb=p_xform.elements[0].dot(xf_points[0]);
723 dp = p_xform.elements[0].dot(xf_points[1]);
727 dp = p_xform.elements[0].dot(xf_points[2]);
731 dp = p_xform.elements[0].dot(xf_points[3]);
741 maxa=p_xform.elements[1].dot(xf_points2[0]);
744 dp = p_xform.elements[1].dot(xf_points2[1]);
748 dp = p_xform.elements[1].dot(xf_points2[2]);
752 dp = p_xform.elements[1].dot(xf_points2[3]);
756 maxb=p_xform.elements[1].dot(xf_points[0]);
759 dp = p_xform.elements[1].dot(xf_points[1]);
763 dp = p_xform.elements[1].dot(xf_points[2]);
767 dp = p_xform.elements[1].dot(xf_points[3]);
807 Vector2 v = p_vec - elements[2];
815 Rect2 Matrix32::xform(
const Rect2& p_rect)
const {
817 Vector2 x=elements[0]*p_rect.size.x;
818 Vector2 y=elements[1]*p_rect.size.y;
819 Vector2 pos = xform( p_rect.pos );
823 new_rect.expand_to( pos+x );
824 new_rect.expand_to( pos+y );
825 new_rect.expand_to( pos+x+y );
829 void Matrix32::set_rotation_and_scale(real_t p_rot,
const Size2& p_scale) {
831 elements[0][0]=Math::cos(p_rot)*p_scale.x;
832 elements[1][1]=Math::cos(p_rot)*p_scale.y;
833 elements[0][1]=-Math::sin(p_rot)*p_scale.x;
834 elements[1][0]=Math::sin(p_rot)*p_scale.y;
838 Rect2 Matrix32::xform_inv(
const Rect2& p_rect)
const {
841 xform_inv( p_rect.pos ),
842 xform_inv(
Vector2(p_rect.pos.x,p_rect.pos.y+p_rect.size.y ) ),
843 xform_inv(
Vector2(p_rect.pos.x+p_rect.size.x,p_rect.pos.y+p_rect.size.y ) ),
844 xform_inv(
Vector2(p_rect.pos.x+p_rect.size.x,p_rect.pos.y ) )
848 new_rect.pos=ends[0];
849 new_rect.expand_to(ends[1]);
850 new_rect.expand_to(ends[2]);
851 new_rect.expand_to(ends[3]);
Definition: math_2d.h:422
Definition: math_2d.h:369
Rect2i clip(const Rect2i &p_rect) const
Definition: math_2d.h:460
Definition: math_2d.h:204
Rect2 merge(const Rect2 &p_rect) const
Definition: math_2d.h:288
Rect2 clip(const Rect2 &p_rect) const
Definition: math_2d.h:269
Rect2i merge(const Rect2i &p_rect) const
Definition: math_2d.h:479
Definition: math_2d.h:554