mxArray*
ParticleSimulator::SaveConvexity()
{
	ParticleFactory* factory = ParticleFactory::getInstance();
	const int dims[] = { factory->particles.size(), 3 };
	vector<float> F(dims[0] * dims[1]);
	for (int i = 0; i < dims[0]; ++i)
	{
		MovingParticle* p = factory->particles[i];
		CParticleF pr = p->project(p->created + 0.1);
		SetData2(F, i, 0, dims[0], dims[1], pr.m_X);
		SetData2(F, i, 1, dims[0], dims[1], pr.m_Y);
		SetData2(F, i, 2, dims[0], dims[1], p->reflexive<=0 ? 0.0f: 1.0f);
	}
	return StoreData(F, mxSINGLE_CLASS, 2, dims);
}
/*
a snapshot provides neighborhood information at a particular point in time. We try to reproduce the configuration of the system 
as accurately as possible. We need to consider the following steps.
1. all particles that are created after the time point need to be removed from the system.
2. all particles that are still active at the time point need to be activated.
3. children of a particle need to be erased if they are created after the time point.
*/
bool
ParticleSimulator::Restore(vector<Snapshot>& snapshots)
{
	ParticleFactory* factory = ParticleFactory::getInstance();
	float time0 = 0;
	for (int i = 0; i < snapshots.size(); ++i)
	{
		if (snapshots[i].getTime() > time0)
		{
			time0 = snapshots[i].getTime();
		}
	}
	time = time0;
	for (int i = 0; i < factory->particles.size(); ++i)
	{
		MovingParticle* p = factory->particles[i];
		for (int j = 0; j < 2; ++j)
		{
			if (p->children[j] != NULL && p->children[j]->created > time)
			{
				p->children[j] = NULL;
			}
		}
	}

	vector<MovingParticle*> toremove;
	for (int i = 0; i < factory->particles.size(); ++i)
	{
		MovingParticle* p = factory->particles[i];
		if (p->created > time)
		{
			toremove.push_back(p);
		}
	}
	//activate those that are still active.
	vector<MovingParticle*> toactivate;
	for (int i = 0; i < factory->particles.size(); ++i)
	{
		MovingParticle* p = factory->particles[i];
		if (p->bActive == false && p->created < time && p->time > time)
		{
			toactivate.push_back(p);
		}
	}

	//set neighbors
	for (int i = 0; i < snapshots.size(); ++i)
	{
		float t = snapshots[i].getTime();
		for (int j = 0; j < snapshots[i].size(); ++j)
		{
			int id = snapshots[i].get(j);
			int id0 = snapshots[i].get(j == 0 ? snapshots[i].size() - 1 : j - 1);
			int id2 = snapshots[i].get(j == snapshots[i].size() - 1 ? 0 : j + 1);
			MovingParticle* p = factory->get(id);
			if (p == NULL)
			{
				return false;
			}
			p->setNeighbors(p, factory->get(id0), factory->get(id2));
		}
	}

	//delete future particles from memory
	for (int i = 0; i < toremove.size(); ++i)
	{
		factory->remove(toremove[i]);
	}
	//factory->activeSet.clear();
	for (int i = 0; i < toactivate.size(); ++i)
	{
		factory->activeSet.insert(toactivate[i]);
	}
	//recalculate positions
	for (set<MovingParticle*>::iterator it = factory->activeSet.begin(); it != factory->activeSet.end(); ++it)
	{
		MovingParticle* p = *it;
		p->p = p->project(time);
		p->time = time;
	}
	//recalculate events
	for (set<MovingParticle*>::iterator it = factory->activeSet.begin(); it != factory->activeSet.end(); ++it)
	{
		(*it)->event.type == UnknownEvent;
		(*it)->updateEvent();
	}
	return true;
}