Пример #1
0
/*
This function reflects an animated circle on a line segment.
It should first make sure that the animated point is intersecting with the line 

 - Parameters
	- Ps:		The center's starting location
	- Pe:		The center's ending location
	- Radius:	The circle's radius
	- LS:		The line segment
	- Pi:		This will be used to store the intersection point's coordinates (In case there's an intersection)
	- R:		Reflected vector R

 - Returned value: Intersection time t
	- -1.0f:				If there's no intersection
	- Intersection time:	If there's an intersection
*/
float ReflectAnimatedCircleOnStaticLineSegment(Vector2D *Ps, Vector2D *Pe, float Radius, LineSegment2D *LS, Vector2D *Pi, Vector2D *R)
{
	float IntersectionTime = AnimatedCircleToStaticLineSegment(Ps, Pe, Radius, LS, Pi);

	float Scalar;

	Vector2D I;
	Vector2D S;

	Vector2D Vector;

	if (IntersectionTime == NO_INTERSECTION)
	{
		return NO_INTERSECTION;
	}

	Vector2DSub(&I, Pe, Pi); // Creates the I vector
	Scalar = Vector2DDotProduct(&I, &LS->mN); // Creates the scalar needed for the s vector
	Vector2DScale(&S, &LS->mN, Scalar); // Creates the S vector

	Vector2DSub(R, &I, &S);
	Vector2DSub(R, R, &S);

	return IntersectionTime;
}
Пример #2
0
/*
This function reflects an animated circle on a static circle.
It should first make sure that the animated circle is intersecting with the static one 

 - Parameters
	- Center0s:		The starting position of the animated circle's center 
	- Center0e:		The ending position of the animated circle's center 
	- Radius0:		The animated circle's radius
	- Center1:		The static circle's center
	- Radius1:		The static circle's radius
	- Pi:			This will be used to store the intersection point's coordinates (In case there's an intersection)
	- R:			Reflected vector R

 - Returned value: Intersection time t
	- -1.0f:		If there's no intersection
	- Intersection time:	If there's an intersection
*/
float ReflectAnimatedCircleOnStaticCircle(Vector2D *Center0s, Vector2D *Center0e, float Radius0, Vector2D *Center1, float Radius1, Vector2D *Pi, Vector2D *R)
{
	Vector2D U;  //(U is the adjusted normal) 
	Vector2D M;  //(M is from Ps to Pi)
	Vector2D Normal;

	float UScalar;
	float IntersectionTime = AnimatedCircleToStaticCircle(Center0s, Center0e, Radius0, Center1, Radius1, Pi);

	if (IntersectionTime == -1.0f)
		return -1.0f;

	// Calculating Normal
	Vector2DSub(&Normal, Pi, Center1);
	Vector2DNormalize(&Normal, &Normal);

	// Calculating Vector M (M is from Ps to Pi)
	Vector2DSub(&M, Center0s, Pi);

	//Calculating Vector U (U is the adjusted normal)
	UScalar = Vector2DDotProduct(&M, &Normal);
	Vector2DScale(&U, &Normal, UScalar);

	//Calculating R (R is the reflection Vector)
	Vector2DScale(&U, &U, 2.0f);
	Vector2DSub(R, &U, &M);
	Vector2DNormalize(R, R);

	return IntersectionTime;
}
Пример #3
0
/*
This function checks whether an animated circle is colliding with a line segment

 - Parameters
	- Ps:		The center's starting location
	- Pe:		The center's ending location
	- Radius:	The circle's radius
	- LS:		The line segment
	- Pi:		This will be used to store the intersection point's coordinates (In case there's an intersection)

 - Returned value: Intersection time t
	- -1.0f:				If there's no intersection
	- Intersection time:	If there's an intersection
*/
float AnimatedCircleToStaticLineSegment(Vector2D *Ps, Vector2D *Pe, float Radius, LineSegment2D *LS, Vector2D *Pi)
{
	Vector2D Vector;

	Vector2D P1Vector;
	Vector2D P0Vector;

	float InsideorOutside;
	float P1P0Dot;
	float IntersectionTime;
	float temp1;
	float temp2;

	if (StaticPointToStaticLineSegment(Ps, LS) < -Radius && StaticPointToStaticLineSegment(Pe, LS) < -Radius)
	{
	return NO_INTERSECTION;
	}
	else if (StaticPointToStaticLineSegment(Ps, LS) > Radius && StaticPointToStaticLineSegment(Pe, LS) > Radius)
	{
	return NO_INTERSECTION;
	}

	InsideorOutside = StaticPointToStaticLineSegment(Ps, LS);

	temp1 = Vector2DDotProduct(&LS->mN, Ps);
	temp1 = LS->mNdotP0 - temp1;

	if (InsideorOutside > 0)
		temp1 += Radius;
	else if (InsideorOutside < 0)
		temp1 -= Radius;

	Vector2DSub(&Vector, Pe, Ps);

	temp2 = Vector2DDotProduct(&LS->mN, &Vector);

	IntersectionTime = temp1 / temp2;

	if (IntersectionTime >= 0 && IntersectionTime <= 1)
	{
		Vector2DScale(&Vector, &Vector, IntersectionTime);
		Vector2DAdd(Pi, Ps, &Vector);

		Vector2DSub(&P1Vector, Pi, &LS->mP1);
		Vector2DSub(&P0Vector, Pi, &LS->mP0);

		P1P0Dot = Vector2DDotProduct(&P0Vector, &P1Vector);

		if (P1P0Dot < 0)
		{
			return IntersectionTime;
		}
		else
		{
			return NO_INTERSECTION;
		}
	}

	return NO_INTERSECTION;
}
Пример #4
0
/*
This function checks whether an animated point is colliding with a static circle

 - Parameters
	- Ps:		The point's starting location
	- Pe:		The point's ending location
	- Center:	The circle's center
	- Radius:	The circle's radius
	- Pi:		This will be used to store the intersection point's coordinates (In case there's an intersection)

 - Returned value: Intersection time t
	- -1.0f:		If there's no intersection
	- Intersection time:	If there's an intersection
*/
float AnimatedPointToStaticCircle(Vector2D *Ps, Vector2D *Pe, Vector2D *Center, float Radius, Vector2D *Pi)
{
	float A = 0;
	float B = 0;
	float C = 0;
	float Deter = 0;
	float IntersectionTime = 0;
	float Ti0 = 0;
	float Ti1 = 0;

	Vector2D PstoCenter;
	Vector2D Vector;
	Vector2D Temp;

	Vector2DSub(&Vector, Pe, Ps);
	Vector2DSub(&PstoCenter, Center, Ps);
	Vector2DSub(&Temp, Center, Ps);

	// A Solved Here!
	A = Vector2DDotProduct(&Vector, &Vector);

	// B Solved Here!
	Vector2DScale(&Temp, &PstoCenter, -2.0f);
	B = Vector2DDotProduct(&Temp, &Vector);

	// C Solved Here!
	C = Vector2DDotProduct(&PstoCenter, &PstoCenter);
	C -= (Radius * Radius);

	// Solving for (B^2 - 4AC)
	Deter += (B * B);
	Deter -= (4 * A * C);

	if (Deter < 0)
		return -1.0f;
	else if (Deter == 0)
		IntersectionTime = (-B / (2 * A));
	else if (Deter > 0)
	{
		Ti0 = (-B - sqrt(Deter)) / (2 * A);
		Ti1 = (-B + sqrt(Deter)) / (2 * A);

		if (Ti0 > Ti1)
			IntersectionTime = Ti1;
		else
			IntersectionTime = Ti0;
	}
	Vector2DScaleAdd(Pi, &Vector, Ps, IntersectionTime);

	return IntersectionTime;
}
/*
This function checks if the point P is colliding with the circle whose
center is "Center" and radius is "Radius"
*/
int StaticPointToStaticCircle(Vector2D *pP, Vector2D *pCenter, float Radius)
{
	Vector2D distVec;
	float distance = 0;
	Vector2DSub(&distVec,  pP, pCenter);
	distance = Vector2DLength(&distVec);
		// If Distance is less than or equal to radius, its colliding
	if(distance <= Radius)
	{
		return 1;
	}
	else
		return 0;
}
Пример #6
0
/*
This function checks whether an animated circle is colliding with a static circle

 - Parameters
	- Center0s:		The starting position of the animated circle's center 
	- Center0e:		The ending position of the animated circle's center 
	- Radius0:		The animated circle's radius
	- Center1:		The static circle's center
	- Radius1:		The static circle's radius
	- Pi:			This will be used to store the intersection point's coordinates (In case there's an intersection)

 - Returned value: Intersection time t
	- -1.0f:		If there's no intersection
	- Intersection time:	If there's an intersection
*/
float AnimatedCircleToStaticCircle(Vector2D *Center0s, Vector2D *Center0e, float Radius0, Vector2D *Center1, float Radius1, Vector2D *Pi)
{
	float A = 0;
	float B = 0;
	float C = 0;
	float Deter = 0;
	float IntersectionTime = 0;
	float Ti0 = 0;
	float Ti1 = 0;
	float M;

	Vector2D PstoCenter;
	Vector2D Vector;
	Vector2D Temp;

	Vector2DSub(&Vector, Center0e, Center0s);

	Vector2DSub(&PstoCenter, Center1, Center0s);
	Vector2DSub(&Temp, Center1, Center0s);

	M = Vector2DDotProduct(&PstoCenter, &Vector);
	if (M < 0)
		return -1.0f;

	// A Solved Here!
	A = Vector2DDotProduct(&Vector, &Vector);

	// B Solved Here!
	Vector2DScale(&Temp, &PstoCenter, -2.0f);
	B = Vector2DDotProduct(&Temp, &Vector);

	// C Solved Here!
	C = Vector2DDotProduct(&PstoCenter, &PstoCenter);
	C -= (Radius1 + Radius0) * (Radius1 + Radius0);

	// Solving for (B^2 - 4AC)
	Deter += (B * B);
	Deter -= (4 * A * C);

	if (Deter < 0)
		return -1.0f;
	else if (Deter == 0)
		IntersectionTime = (-B / (2 * A));
	else if (Deter > 0)
	{
		Ti0 = (-B - sqrt(Deter)) / (2 * A);
		Ti1 = (-B + sqrt(Deter)) / (2 * A);

		if (Ti0 > Ti1)
			IntersectionTime = Ti1;
		else
			IntersectionTime = Ti0;
	}
	if (IntersectionTime > 0 && IntersectionTime < 1)
	{
		Vector2DScaleAdd(Pi, &Vector, Center0s, IntersectionTime);
		return IntersectionTime;
	}
	return -1.0f;
	
}
int main()
{
	Vector2D v1, v2, v3, result;
	float scale;
	Matrix2D id, m0, m1;
	Vector2D  u;
	float d, x, y;
	long  n;
	long i, j;
	float radius;

	v1.x = v1.y = 7.0f;
	Vector2DZero(&v1);
	result.x = result.y = 0.0f;
	printf("Vector2DZero: %s\n", (CompareVector2D(&result, &v1) < EPSILON) ? "Pass" : "Fail");


	Vector2DSet(&v1, 1.0f, 2.0f);
	result.x = 1.0f;	result.y = 2.0f;
	printf("Vector2DSet: %s\n", (CompareVector2D(&result, &v1) < EPSILON) ? "Pass" : "Fail");


	v1.x = 2.0f; v1.y = -4.0f;
	Vector2DNeg(&v2, &v1);
	result.x = -2.0f;	result.y = 4.0f;
	printf("Vector2DNeg: %s\n", (CompareVector2D(&result, &v2) < EPSILON) ? "Pass" : "Fail");

	v1.x = 2.0f; v1.y = -4.0f;
	v2.x = 1.0f; v2.y = 7.0f;
	Vector2DAdd(&v3, &v1, &v2);
	result.x = result.y = 3.0f;
	printf("Vector2DAdd: %s\n", (CompareVector2D(&result, &v3) < EPSILON) ? "Pass" : "Fail");


	v1.x = 2.0f; v1.y = -4.0f;
	v2.x = 1.0f; v2.y = 7.0f;
	Vector2DSub(&v3, &v1, &v2);
	result.x = 1.0f;	result.y = -11.0f;
	printf("Vector2DSub: %s\n", (CompareVector2D(&result, &v3) < EPSILON) ? "Pass" : "Fail");


	v1.x = 3.0f; v1.y = 4.0f;
	Vector2DNormalize(&v2, &v1);
	result.x = 0.6f;	result.y = 0.8f;
	printf("Vector2DNormalize: %s\n", (CompareVector2D(&result, &v2) < EPSILON) ? "Pass" : "Fail");


	v1.x = 2.0f; v1.y = -5.0f;
	Vector2DScale(&v2, &v1, 3.0f);
	result.x = 6.0f;	result.y = -15.0f;
	printf("Vector2DScale: %s\n", (CompareVector2D(&result, &v2) < EPSILON) ? "Pass" : "Fail");

	v1.x = 2.0f; v1.y = -5.0f;
	v2.x = 6.0f; v2.y =  2.0f;
	scale = 3.0f;
	Vector2DScaleAdd(&v3, &v1, &v2, scale);
	result.x = 12.0f; result.y = -13.0f;
	printf("Vector2DScaleAdd: %s\n", (CompareVector2D(&result, &v3) < EPSILON) ? "Pass" : "Fail");

	Vector2DScaleSub(&v3, &v1, &v2, scale);
	result.x = 0.f; result.y = -17.f;
	printf("Vector2DScaleSub: %s\n", (CompareVector2D(&result, &v3) < EPSILON) ? "Pass" : "Fail");

	v1.x = 3.0f; v1.y = -4.0f;
	printf("Vector2DLength: %s\n", (fabs(Vector2DLength(&v1) - 5.0f)  < EPSILON) ? "Pass" : "Fail");


	v1.x = 3.0f; v1.y = -4.0f;
	printf("Vector2DSquareLength: %s\n", (fabs(Vector2DSquareLength(&v1) - 25.0f)  < EPSILON) ? "Pass" : "Fail");


	v1.x = 2.0f;	v1.y = 3.0f;
	v2.x = 4.0f;	v2.y = -1.0f;
	printf("Vector2DDistance: %s\n", (fabs(Vector2DDistance(&v1, &v2) - 4.472136)  < EPSILON) ? "Pass" : "Fail");


	v1.x = 2.0f;	v1.y = 3.0f;
	v2.x = 4.0f;	v2.y = -1.0f;
	printf("Vector2DSquareDistance: %s\n", (fabs(Vector2DSquareDistance(&v1, &v2) - 20.0f)  < EPSILON) ? "Pass" : "Fail");


	v1.x = 3.0f;	v1.y = 2.0f;
	v2.x = 4.0f;	v2.y = -6.0f;
	printf("Vector2DDotProduct: %s\n", (fabs(Vector2DDotProduct(&v1, &v2)) < EPSILON) ? "Pass" : "Fail");


	printf("\n------Testing StaticPointToStaticCircle------\n\n");
	v1.x = 10.f; v1.y = 10.f;
	v2.x = 11.4f; v2.y = 11.4f;
	radius = 2.f;
	printf("StaticPointToStaticCircle Collision: %s\n", (StaticPointToStaticCircle(&v2, &v1, radius)) ? "Pass" : "Fail" );

	v2.x = 12.f; v2.y = 12.f;
	printf("StaticPointToStaticCircle Non Collision: %s\n", (!StaticPointToStaticCircle(&v2, &v1, radius)) ? "Pass" : "Fail" );



	printf("\n------Running Matrix Tests------\n\n");



	// create an id matrix for reference
	for (i = 0; i < 3; i++)
		for (j = 0; j < 3; j++)
			id.m[j][i] = (i == j) ? 1.0f : 0.0f;

	// ====================
	// test Matrix2DIdentity
	// ====================

	Matrix2DIdentity(&m0);
	d = CompareMatrix2D(&id, &m0);
	printf("Matrix2DIdentity : %s\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail");

	// ====================
	// test Matrix2DTrans
	// ====================

	// generate 2 random numbers
	x = 2.0f * rand() / (float)(RAND_MAX) - 1.0f;
	y = 2.0f * rand() / (float)(RAND_MAX) - 1.0f;

	Matrix2DTranslate(&m0, x, y);
	m0.m[0][2] -= x;
	m0.m[1][2] -= y;
	printf("Matrix2DTranslate: %s\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail");

	// ====================
	// test Matrix2DScale
	// ====================

	// generate 2 random numbers
	x = 2.0f * rand() / (float)(RAND_MAX) - 1.0f;
	y = 2.0f * rand() / (float)(RAND_MAX) - 1.0f;

	Matrix2DScale(&m0, x, y);
	m0.m[0][0] /= x;
	m0.m[1][1] /= y;

	printf("Matrix2DScale    : %s\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail");

	// ====================
	// test Matrix2DConcat
	// ====================

	// generate 2 random numbers
	x = 2.0f * rand() / (float)(RAND_MAX) - 1.0f;
	y = 2.0f * rand() / (float)(RAND_MAX) - 1.0f;

	Matrix2DTranslate (&m0, x, y);
	Matrix2DScale (&m1, x, y);
	Matrix2DConcat(&m0, &m0, &m1);
	m0.m[0][2] -= x;
	m0.m[1][2] -= y;
	m0.m[0][0] /= x;
	m0.m[1][1] /= y;

	printf("Matrix2DConcat 1 : %s\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail");

	// generate 2 random numbers
	x = 2.0f * rand() / (float)(RAND_MAX) - 1.0f;
	y = 2.0f * rand() / (float)(RAND_MAX) - 1.0f;

	Matrix2DTranslate (&m0, x, y);
	Matrix2DScale (&m1, x, y);
	Matrix2DConcat(&m0, &m1, &m0);
	m0.m[0][2] -= x * x;
	m0.m[1][2] -= y * y;
	m0.m[0][0] /= x;
	m0.m[1][1] /= y;

	printf("Matrix2DConcat 2 : %s\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail");

	// ====================
	// test Matrix2DRotRad
	// ====================

	n = (rand() % 16) + 15;
	Matrix2DIdentity(&m0);
	Matrix2DRotRad  (&m1, 2.0f * PI / n);

	for (i = 0; i < n; i++)
		Matrix2DConcat(&m0, &m1, &m0);

	printf("Matrix2DRotRad   : %s (%d)\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail", n);

	// ====================
	// test Matrix2DRotDeg
	// ====================

	n = (rand() % 16) + 15;
	Matrix2DIdentity(&m0);
	Matrix2DRotDeg  (&m1, 360.0f / n);

	for (i = 0; i < n; i++)
		Matrix2DConcat(&m0, &m1, &m0);

	printf("Matrix2DRotDeg   : %s (%d)\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail", n);

	// ====================
	// test Matrix2DTranspose
	// ====================

	Matrix2DRotRad   (&m0, rand() / (float)(RAND_MAX) * 2.0f * PI);
	Matrix2DTranspose(&m1, &m0);
	Matrix2DConcat   (&m0, &m1, &m0);

	printf("Matrix2DTranspose: %s\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail");

	// ====================
	// test Matrix2DMultVec
	// ====================

	// generate 2 random numbers
	x = 2.0f * rand() / (float)(RAND_MAX) - 1.0f;
	y = 2.0f * rand() / (float)(RAND_MAX) - 1.0f;

	n = (rand() % 16) + 15;
	Vector2DSet		(&u, x, y);
	Matrix2DRotRad	(&m0, 2.0f * PI / n);

	for (i = 0; i < n; i++)
		Matrix2DMultVec(&u, &m0, &u);

	printf("Matrix2DMultVec  : %s\n", ((fabs(u.x - x) + fabs(u.y - y)) < EPSILON) ? "Pass" : "Fail");

	// generate 2 random numbers
	x = 2.0f * rand() / (float)(RAND_MAX) - 1.0f;
	y = 2.0f * rand() / (float)(RAND_MAX) - 1.0f;

	n = (rand() % 16) + 15;
	Vector2DSet		(&u, x, y);
	Matrix2DTranslate	(&m0, x, y);

	for (i = 1; i < n; i++)
		Matrix2DMultVec(&u, &m0, &u);

	printf("Matrix2DMultVec  : %s\n", ((fabs(u.x - x * n) + fabs(u.y - y * n)) < EPSILON) ? "Pass" : "Fail");

	printf("\n------Testing New Collision Functions------\n\n");

	//StaticPointToStaticRect
	Vector2DSet(&v1, 1.f, 1.f); //point
	Vector2DSet(&v2, 0.f, 0.f); //rect
	printf("StaticPointToStaticRect Collision: %s\n", (StaticPointToStaticRect(&v1, &v2, 2.f, 2.f) ? "Pass" : "Fail"));
	printf("StaticPointToStaticRect Non Collision: %s\n\n", (!StaticPointToStaticRect(&v1, &v2, 1.f, 1.f) ? "Pass" : "Fail"));

	//StaticCircleToStaticCircle
	Vector2DSet(&v1, 2.f, 0.f);
	printf("StaticCircleToStaticCircle Collision Touch: %s\n", (StaticCircleToStaticCircle(&v1, 1.f, &v2, 1.f) ? "Pass" : "Fail"));
	printf("StaticCircleToStaticCircle Collision: %s\n", (StaticCircleToStaticCircle(&v1, 2.f, &v2, 1.f) ? "Pass" : "Fail"));
	printf("StaticCircleToStaticCircle Non Collision: %s\n\n", (!StaticCircleToStaticCircle(&v1, 0.5f, &v2, 1.f) ? "Pass" : "Fail"));

	//StaticRectToStaticRect
	Vector2DSet(&v1, 2.f, 2.f);
	printf("StaticRectToStaticRect Non Collision: %s\n", (!StaticRectToStaticRect(&v1, 1.f, 1.f, &v2, 1.f, 1.f) ? "Pass" : "Fail"));
	printf("StaticRectToStaticRect Collision Touch: %s\n", (StaticRectToStaticRect(&v1, 2.f, 2.f, &v2, 2.f, 2.f) ? "Pass" : "Fail"));
	printf("StaticRectToStaticRect Collision Intersect: %s\n", (StaticRectToStaticRect(&v1, 3.f, 3.f, &v2, 3.f, 3.f) ? "Pass" : "Fail"));

	return 1;
}
Пример #8
0
void Vector2DScaleSub(Vector2D &Result, const Vector2D &Vec0, const Vector2D &Vec1, float c)
{
    Vector2DScale(Result, Vec0, c);
    Vector2DSub(Result, Result, Vec1);
}
Пример #9
0
void Vector2DScaleSub(Vector2D *pResult, Vector2D *pVec0, Vector2D *pVec1, float c) {
	Vector2DScale(pResult, pVec0, c);
	Vector2DSub(pResult, pResult, pVec1);
}