216 lines
3.9 KiB
C++
216 lines
3.9 KiB
C++
#include "vector2D.h"
|
|
#include <num/num.h>
|
|
|
|
|
|
|
|
libnum::num32 sqrt_num32(libnum::num32 v)
|
|
{
|
|
uint32_t t, q, b, r;
|
|
r = v.v;
|
|
b = 0x40000000;
|
|
q = 0;
|
|
while( b > 0x40 )
|
|
{
|
|
t = q + b;
|
|
if( r >= t )
|
|
{
|
|
r -= t;
|
|
q = t + b;
|
|
}
|
|
r <<= 1;
|
|
b >>= 1;
|
|
}
|
|
q >>= 8;
|
|
libnum::num32 ret;
|
|
ret.v = q;
|
|
return ret;
|
|
}
|
|
|
|
|
|
Vector2D::Vector2D()
|
|
{
|
|
this->x = 0.0;
|
|
this->y = 0.0;
|
|
}
|
|
|
|
Vector2D::Vector2D( float x, float y )
|
|
{
|
|
this->x = libnum::num32(x);
|
|
this->y = libnum::num32(y);
|
|
}
|
|
|
|
Vector2D::Vector2D( libnum::num32 x, libnum::num32 y )
|
|
{
|
|
this->x = x;
|
|
this->y = y;
|
|
}
|
|
|
|
Vector2D::~Vector2D()
|
|
{
|
|
this->x = 0.0;
|
|
this->y = 0.0;
|
|
}
|
|
|
|
Vector2D Vector2D::Clone( void )
|
|
{
|
|
Vector2D NewVector( this->x, this->y );
|
|
return NewVector;
|
|
}
|
|
|
|
void Vector2D::AddVectors( Vector2D a, Vector2D b )
|
|
{
|
|
this->x = a.x + b.x;
|
|
this->y = a.y + b.y;
|
|
}
|
|
|
|
void Vector2D::Add( Vector2D v, libnum::num32 scale )
|
|
{
|
|
this->x += v.x * scale;
|
|
this->y += v.y * scale;
|
|
}
|
|
|
|
void Vector2D::SubtractVectors( Vector2D a, Vector2D b )
|
|
{
|
|
this->x = a.x - b.x;
|
|
this->y = a.y - b.y;
|
|
}
|
|
|
|
void Vector2D::Subtract( Vector2D v, libnum::num32 scale )
|
|
{
|
|
this->x -= v.x * scale;
|
|
this->y -= v.y * scale;
|
|
}
|
|
|
|
libnum::num32 Vector2D::Length( void )
|
|
{
|
|
return sqrt_num32( this->x * this->x + this->y * this->y );
|
|
}
|
|
|
|
void Vector2D::Scale( libnum::num32 scale )
|
|
{
|
|
this->x *= scale;
|
|
this->y *= scale;
|
|
}
|
|
|
|
libnum::num32 Vector2D::Dot( Vector2D v )
|
|
{
|
|
return ( this->x * v.x + this->y * v.y );
|
|
}
|
|
|
|
Vector2D Vector2D::Perp( void )
|
|
{
|
|
Vector2D temp( -this->y, this->x );
|
|
return temp;
|
|
}
|
|
|
|
|
|
bool CollisionDroite(Point2D A,Point2D B, Circle C)
|
|
{
|
|
Vector2D u;
|
|
u.x = B.x - A.x;
|
|
u.y = B.y - A.y;
|
|
Vector2D AC;
|
|
AC.x = C.x - A.x;
|
|
AC.y = C.y - A.y;
|
|
libnum::num numerateur = u.x*AC.y - u.y*AC.x; // norme du vecteur v
|
|
if (numerateur <0)
|
|
numerateur = -numerateur ; // valeur absolue ; si c'est négatif, on prend l'opposé.
|
|
libnum::num denominateur = sqrt_num32(u.x*u.x + u.y*u.y); // norme de u
|
|
libnum::num CI = numerateur / denominateur;
|
|
|
|
if (CI<C.r)
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
|
|
bool CollisionSegment(Point2D A,Point2D B, Circle C)
|
|
{
|
|
if (CollisionDroite(A,B,C) == false)
|
|
return false; // si on ne touche pas la droite, on ne touchera jamais le segment
|
|
|
|
Vector2D AB,AC,BC;
|
|
AB.x = B.x - A.x;
|
|
AB.y = B.y - A.y;
|
|
AC.x = C.x - A.x;
|
|
AC.y = C.y - A.y;
|
|
BC.x = C.x - B.x;
|
|
BC.y = C.y - B.y;
|
|
|
|
libnum::num pscal1 = AB.x*AC.x + AB.y*AC.y; // produit scalaire
|
|
libnum::num pscal2 = (-AB.x)*BC.x + (-AB.y)*BC.y; // produit scalaire
|
|
|
|
if (pscal1>=0 && pscal2>=0)
|
|
return true; // I entre A et B, ok.
|
|
|
|
/*
|
|
// dernière possibilité, A ou B dans le cercle
|
|
if (CollisionPoint2DCercle(A,C))
|
|
return true;
|
|
if (CollisionPoint2DCercle(B,C))
|
|
return true;
|
|
*/
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
bool CollisionBorder(Border B, Circle C)
|
|
{
|
|
return CollisionSegment( B.A, B.B, C );
|
|
}
|
|
|
|
|
|
Vector2D GetNormale(Point2D A,Point2D B,Point2D C)
|
|
{
|
|
Vector2D AC,u,N;
|
|
u.x = B.x - A.x;
|
|
u.y = B.y - A.y;
|
|
AC.x = C.x - A.x;
|
|
AC.y = C.y - A.y;
|
|
libnum::num parenthesis = u.x*AC.y-u.y*AC.x; // calcul une fois pour les deux
|
|
|
|
N.x = -u.y*(parenthesis);
|
|
N.y = u.x*(parenthesis);
|
|
|
|
// normalisons
|
|
libnum::num norme = sqrt_num32(N.x*N.x + N.y*N.y);
|
|
N.x/=norme;
|
|
N.y/=norme;
|
|
|
|
return N;
|
|
}
|
|
|
|
Point2D ProjectionI(Point2D A,Point2D B,Point2D C)
|
|
{
|
|
Vector2D u,AC;
|
|
u.x = B.x - A.x;
|
|
u.y = B.y - A.y;
|
|
AC.x = C.x - A.x;
|
|
AC.y = C.y - A.y;
|
|
libnum::num ti = (u.x*AC.x + u.y*AC.y)/(u.x*u.x + u.y*u.y);
|
|
Point2D I;
|
|
I.x = A.x + ti*u.x;
|
|
I.y = A.y + ti*u.y;
|
|
return I;
|
|
}
|
|
|
|
Vector2D ComputeVectorRebound(Vector2D v,Vector2D N)
|
|
{
|
|
Vector2D v2;
|
|
libnum::num pscal = (v.x*N.x + v.y*N.y);
|
|
v2.x = v.x -2*pscal*N.x;
|
|
v2.y = v.y -2*pscal*N.y;
|
|
return v2;
|
|
}
|
|
|
|
Border::Border()
|
|
{
|
|
|
|
}
|
|
|
|
Border::~Border()
|
|
{
|
|
|
|
} |