Пример #1
0
/*
A unit vector from o to x in 2D
*/
CParticleF
NormalizedDirection(CParticleF& x, CParticleF& o)
{
	float dx = x.m_X - o.m_X;
	float dy = x.m_Y - o.m_Y;
	float len = sqrt(dx*dx + dy*dy);
	if (len > 1.0e-5)
	{
		return CParticleF(dx / len, dy / len);
	}
	else
	{
		return CParticleF(0.0f, 0.0f);
	}
}
Пример #2
0
/*
Check if lines a-b and c-d are parallel.
*/
bool
isParallel(CParticleF& a, CParticleF& b, CParticleF& c, CParticleF& d, float precision)
{
	CParticleF x = UnitVector(CParticleF(b.m_X - a.m_X, b.m_Y - a.m_Y, b.m_Z - a.m_Z));
	CParticleF y = UnitVector(CParticleF(d.m_X - c.m_X, d.m_Y - c.m_Y, d.m_Z - c.m_Z));

	CParticleF z = crossProduct(x, y);
	if (sqrt(z.m_X*z.m_X + z.m_Y*z.m_Y + z.m_Z*z.m_Z) < precision)
	{
		return true;
	}
	else
	{
		return false;
	}
}
bool 
LinkedTriple::updateFate()
{
	if (frontSupporters.size() == 0) return false;

	/*float sx = 0, sy = 0, st = 0;
	for (int i = 0; i < awaySupporters.size(); ++i)
	{
		LinkedTriple* t = awaySupporters[i];
		float c = compatibility(t);
		float s = _timeToClosestEncounter(t);
		sx += s * v[0] * t->prob;
		sy += s * v[1] * t->prob;
		st += t->prob;
	}
	fate = CParticleF(p->getX() + sx / st, p->getY() + sy / st);*/
	LinkedTriple* b = best();
	if (b == NULL) return false;

	float s = this->_timeToClosestEncounter(b);
	fate = CParticleF(p->getX() + s * v[0], p->getY() + s * v[1]); 
	return true;
}
Пример #4
0
/*
return a unit vector that bisects the angle formed by three points: a-o-b.
*/
CParticleF
bisector(CParticleF& o, CParticleF& a, CParticleF& b)
{
	CParticleF x = NormalizedDirection(a, o);
	CParticleF y = NormalizedDirection(b, o);
	CParticleF z((x.m_X + y.m_X) / 2, (x.m_Y + y.m_Y) / 2);
	float vx = z.m_X;
	float vy = z.m_Y;
	float len0 = sqrt(vx*vx + vy*vy);
	if (len0 <= 1.0e-5) //this is a colinear point. 
	{
		float ang = GetVisualDirection(b.m_X, b.m_Y, a.m_X, a.m_Y) - PI / 2.0;
		vx = cos(ang);
		vy = sin(ang);
	}
	else
	{
		vx = vx / len0;
		vy = vy / len0;
	}
	CParticleF bs(o.m_X + vx, o.m_Y + vy);

	//There are two bisector directions. 
	//We consistently choose one that is in clock-wise direction.
	vector<CParticleF> pnts(4);
	pnts[0] = o;
	pnts[1] = a;
	pnts[2] = bs;
	pnts[3] = b;
	if (ClockWise(pnts)<0)
	{
		vx = -vx;
		vy = -vy;
	}
	return CParticleF(vx, vy);
}
bool
ParticleSimulator::LoadParticles(vector<float>& F, const int* dims)
{
	ParticleFactory* factory = ParticleFactory::getInstance();
	factory->clean();
	this->time = 0.0f;
	map<int, MovingParticle*> id2particle;
	vector<int> vchild1;
	vector<int> vchild2;
	vector<int> vparent1;
	vector<int> vparent2;
	vector<int> vprev;
	vector<int> vnext;
	vector<int> veq;
	vector<int> ver;
	for (int i = 0; i < dims[0]; ++i)
	{
		int id = (int)GetData2(F, i, 0, dims[0], dims[1], -1.0f);
		float x0 = GetData2(F, i, 1, dims[0], dims[1], std::numeric_limits<float>::quiet_NaN());
		float y0 = GetData2(F, i, 2, dims[0], dims[1], std::numeric_limits<float>::quiet_NaN());
		float x = GetData2(F, i, 3, dims[0], dims[1], std::numeric_limits<float>::quiet_NaN());
		float y = GetData2(F, i, 4, dims[0], dims[1], std::numeric_limits<float>::quiet_NaN());
		float vx = GetData2(F, i, 5, dims[0], dims[1], std::numeric_limits<float>::quiet_NaN());
		float vy = GetData2(F, i, 6, dims[0], dims[1], std::numeric_limits<float>::quiet_NaN());
		int pid = (int)GetData2(F, i, 7, dims[0], dims[1], -1.0f);
		int nid = (int)GetData2(F, i, 8, dims[0], dims[1], -1.0f);
		MovingParticleType type = int2ParticleType((int)GetData2(F, i, 9, dims[0], dims[1], -1.0f));
		float created = GetData2(F, i, 10, dims[0], dims[1], 0.0f);
		float time = GetData2(F, i, 11, dims[0], dims[1], 0.0f);
		float ref = GetData2(F, i, 12, dims[0], dims[1], 0.0f);
		bool bActive = GetData2(F, i, 13, dims[0], dims[1], 0.0f)>0.0f ? true : false;
		bool bInitialized = (bool)GetData2(F, i, 14, dims[0], dims[1], 0.0f)>0.0f ? true : false;
		bool bUnstable = (bool)GetData2(F, i, 15, dims[0], dims[1], 0.0f)>0.0f ? true : false;
		int parent1 = (int)GetData2(F, i, 16, dims[0], dims[1], -1.0f);
		int parent2 = (int)GetData2(F, i, 17, dims[0], dims[1], -1.0f);
		int child1 = (int)GetData2(F, i, 18, dims[0], dims[1], -1.0f);
		int child2 = (int)GetData2(F, i, 19, dims[0], dims[1], -1.0f);
		EventType etype = int2EventType((int)GetData2(F, i, 20, dims[0], dims[1], 0.0f));
		int eq = (int)GetData2(F, i, 21, dims[0], dims[1], -1.0f);
		int er = (int)GetData2(F, i, 22, dims[0], dims[1], -1.0f);
		float etime = GetData2(F, i, 23, dims[0], dims[1], 0.0f);
		MovingParticle* p = factory->makeParticle(CParticleF(x0, y0), type, created);
		p->p.m_X = x;
		p->p.m_Y = y;
		p->v[0] = vx;
		p->v[1] = vy;
		p->time = time;
		p->bActive = bActive;
		//p->bInitialized = bInitialized;
		p->bUnstable = bUnstable;
		p->event.type = etype;
		p->event.t = etime;
		p->reflexive = ref;
		vparent1.push_back(parent1);
		vparent2.push_back(parent2);
		vchild1.push_back(child1);
		vchild2.push_back(child2);
		p->event.p = p;
		vprev.push_back(pid);
		vnext.push_back(nid);
		veq.push_back(eq);
		ver.push_back(er);
		id2particle[p->id] = p;
		if (p->bActive==false)
		{
			factory->inactivate(p);
		}
		if (p->time > this->time)
		{
			this->time = p->time;
		}
	}
	//now  set prev, next, etc.
	for (int i = 0; i < factory->particles.size(); ++i)
	{
		MovingParticle* p = factory->particles[i];
		p->prev = vprev[i] >= 0 ? id2particle[vprev[i]] : NULL;
		p->next = vnext[i] >= 0 ? id2particle[vnext[i]] : NULL;
		p->event.q = veq[i] >= 0 ? id2particle[veq[i]] : NULL;
		p->event.r = ver[i] >= 0 ? id2particle[ver[i]] : NULL;
		p->parents[0] = vparent1[i] >= 0 ? id2particle[vparent1[i]] : NULL;
		p->parents[1] = vparent2[i] >= 0 ? id2particle[vparent2[i]] : NULL;
		p->children[0] = vchild1[i] >= 0 ? id2particle[vchild1[i]] : NULL;
		p->children[1] = vchild2[i] >= 0 ? id2particle[vchild2[i]] : NULL;
		if (p->id >= MovingParticle::_id)
		{
			MovingParticle::_id = p->id + 1;
		}
	}

	return true;
}
Пример #6
0
/*
Compute a unit vector normal to the side (p->q). The direction is to the left when we are at p and looking toward q.
*/
CParticleF
perpDirection(CParticleF& p, CParticleF& q)
{
	CParticleF nd = NormalizedDirection(q, p);
	return CParticleF(-nd.m_Y, nd.m_X);
}
Пример #7
0
CParticleF
crossProduct(CParticleF& a, CParticleF& b)
{
	return CParticleF(a.m_Y*b.m_Z - a.m_Z*b.m_Y, a.m_Z*b.m_X - a.m_X*b.m_Z, a.m_X*b.m_Y - a.m_Y*b.m_X);
}