Esempio n. 1
0
bool PhysicsProcessor::collidedCircleCircleDirection(Vector2d<float> pos1, float r1,Vector2d<float> pos2, float r2)
{
    //  We check if the circle has collided
    if(collidedCircleCircle(pos1,r1,pos2,r2))
    {
        //  If it has we do further calculations
        Vector2d<float> diff = pos2-pos1;
        Vector2d<float> cp = diff;
        cp.normalise();
        //lastCollisionA.contactPoint = pos1 + (cp * r1);
        //lastCollisionA.ticks = timer->getTicks();

        //  If it has we do further calculations
        diff = pos1 - pos2;
        cp = diff;
        cp.normalise();
        //lastCollisionB.contactPoint = pos2 + (cp * r2);
        //lastCollisionB.ticks = lastCollisionA.ticks;
        return true;
    }
    //return lastCollisionA.hasCollided;
    return false;
}
Esempio n. 2
0
int CollisionDetector::detect(std::vector<Sprite*>& sprites, int spacesPerMetre)
{
	std::vector<collision> collisions;
	size_t n = sprites.size();
	for(size_t i=0; i<n; ++i)
		for(size_t j=i+1; j<n; ++j)
		{
			float dx, dy;
			dx = sprites[i]->getPos().getx() - sprites[j]->getPos().getx();
			dy = sprites[i]->getPos().gety() - sprites[j]->getPos().gety();
			Vector2d normal;
			if(fabs(dx)*spacesPerMetre < (sprites[i]->getWidth() + sprites[j]->getWidth())/2 && fabs(dy)*spacesPerMetre < (sprites[i]->getHeight() + sprites[j]->getHeight())/2)
			{
				normal.setx(dx);
				normal.sety(dy);
				normal.normalise();
				collisions.push_back({i,j,normal});	
			}
		}

	//resolve collisions

	for(size_t i=0; i<collisions.size(); ++i)
	{
		Vector2d relVel = sprites[collisions[i].a]->getVel();
		relVel -= sprites[collisions[i].b]->getVel();
		float sepVel = relVel * collisions[i].normal;
		if(sepVel > 0)
			continue;
		float newSep = -sepVel * (sprites[collisions[i].a]->getBounce()*sprites[collisions[i].b]->getBounce()/2.f);
		float deltaVel = newSep -sepVel;
		float totInvMass = sprites[collisions[i].a]->getInverseMass() + sprites[collisions[i].b]->getInverseMass();		
		float impulse = deltaVel / totInvMass;
		Vector2d impPerIMass = collisions[i].normal * impulse;
		sprites[collisions[i].a]->setVel(sprites[collisions[i].a]->getVel() + impPerIMass * sprites[collisions[i].a]->getInverseMass());
		sprites[collisions[i].b]->setVel(sprites[collisions[i].b]->getVel() + impPerIMass * -sprites[collisions[i].b]->getInverseMass());
	}
	return collisions.size();
}
Esempio n. 3
0
/// Point Collisions
// Check if a point is on a Line
bool PhysicsProcessor::collidedPointLine(Vector2d<float> point,Vector2d<float> lineStart, Vector2d<float> lineEnd)
{
    // Check if the point is actually lineStart or lineEnd
    if(point == lineStart or point == lineEnd)
    {
      /*  lastCollisionA.contactPoint = point;
        lastCollisionA.hasCollided = true;
        lastCollisionA.ticks = timer->getTicks();*/
        return true;
    }

    // Check if line is horizontal or vertical
    // Then we can make quick checks
    if(lineStart.x == lineEnd.x == point.x)
    {
        // Line vertical
        if(point.y >= lineStart.y and point.y <= lineEnd.y)
        {
            /*lastCollisionA.contactPoint = point;
            lastCollisionA.hasCollided = true;
            lastCollisionA.ticks = timer->getTicks();*/
            return true;
        }
    }
    else if(lineStart.y == lineEnd.y == point.y)
    {
        //  line horizontal
        if(point.x >= lineStart.x and point.x <= lineEnd.x)
        {
            /*lastCollisionA.contactPoint = point;
            lastCollisionA.hasCollided = true;
            lastCollisionA.ticks = timer->getTicks();*/
            return true;
        }
    }

    Vector2d<float> AB = lineEnd-lineStart;
    Vector2d<float> AC = point-lineStart;

    float magAB = AB.lengthSquared();
    float magAC = AC.lengthSquared();
    //  If one vector is greater in magnitude than the other, then point is not on the line.
    if(magAC > magAB)
    {
        /*lastCollisionA.contactPoint = point;
        lastCollisionA.hasCollided = false;
        lastCollisionA.ticks = timer->getTicks();*/
        return false;
    }

    //  Now take unit vectors and see if the directions match
    AB.normalise();
    AC.normalise();

    AB = AC - AB;

    //  Same direction so collision has occurred
    if(AB.lengthSquared() == 0)
    {
        /*lastCollisionA.contactPoint = point;
        lastCollisionA.hasCollided = true;
        lastCollisionA.ticks = timer->getTicks();*/
        return true;
    }

    /*lastCollisionA.contactPoint = point;
    lastCollisionA.hasCollided = false;
    lastCollisionA.ticks = timer->getTicks();*/
    return false;
}
Esempio n. 4
0
	bool Span::OnSpan(const Point& p, double* t)const {
		// FAST OnSpan test - assumes that p lies ON the unbounded span
#if _DEBUG
		if(this->returnSpanProperties == false) {
			FAILURE(L"OnSpan - properties no set, incorrect calling code");
		}
#endif
#if 0
		if(NullSpan) {
			*t = 0.0;
			return (p == p0);
		}

		if(p == p0) {
			*t = 0.0;
			return true;
		}

		if(p == p1) {
			*t = 1.0;
			return true;
		}
#endif
		bool ret;
//		if(p == this->p0 || p == this->p1) return true;

		if(dir == LINEAR) {
#if 1
#if _DEBUG
			// check p is on line
			CLine cl(*this);
			double d = fabs(cl.Dist(p));
			if( d > geoff_geometry::TOLERANCE) {
				FAILURE(L"OnSpan - point not on linear span, incorrect calling code");
			}
#endif
#endif
			Vector2d v0(p0, p);
			*t = vs * v0;
//			ret = (*t > - geoff_geometry::TOLERANCE && *t < length + geoff_geometry::TOLERANCE);

			*t = *t / length;
			ret = (*t >= 0 && *t <= 1.0 );

		}
		else {
			// true if p lies on arc span sp (p must be on circle of span)
#if 1
#if _DEBUG
			// check that p lies on the arc
			double d = p.Dist(pc);
			if(FNE(d, radius, geoff_geometry::TOLERANCE)) {
				FAILURE(L"OnSpan - point not on circular span, incorrect calling code");
			}

#endif
#endif
#if 0	// alt method (faster, but doesn't provide t)
			Vector2d v0(p0, p);
			Vector2d v1(p0, p1);

			// check angle to point from start
			double cp;
			ret = ((cp = (dir * (v0 ^ v1))) > 0);
			*t = 0.0;// incorrect !!!
#else
			Vector2d v = ~Vector2d(pc, p);
			v.normalise();
			if(dir == CW) v = -v;

			double ang = IncludedAngle(vs, v, dir);
			*t = ang / angle;
			ret = (*t >= 0 && *t <= 1.0);
#endif
		}

		return ret;
	}