/* Trace a tree around it to construct particles representing vertices of a straight polygon. The implementation is not pretty and may be simplified. But I am not sure at this time. */ void _trace(Vertex<CParticleF>* u, Vertex<CParticleF>*prev, vector<MovingParticle*>& points) { ParticleFactory* factory = ParticleFactory::getInstance(); MovingParticle* particle = factory->makeParticle(u->key, Initial, 0.0f); points.push_back(particle); u->color = Black; CParticleF pu = u->key; CParticleF qu = prev == NULL ? CParticleF(pu.m_X - 1.0, pu.m_Y) : prev->key; int count = 1; while (true) { Vertex<CParticleF>* v = NULL; float minAngle = 3 * PI; //Walk in clock-wise order. for (int i = 0; i < u->aList.size(); ++i) { Vertex<CParticleF>* w = u->aList[i]->v; if (w->color == White) { float ang = GetVisualAngle2(qu.m_X, qu.m_Y, w->key.m_X, w->key.m_Y, pu.m_X, pu.m_Y); if (ang <= 0) ang += 2 * PI; if (ang < minAngle) { minAngle = ang; v = w; } } } if (v != NULL) { count++; _trace(v, u, points); MovingParticle* particle2 = factory->makeParticle(u->key, Initial, 0.0f); points.push_back(particle2); //every branch will result in a new particle. } else { break; } qu = v->key; //update where we are coming from } //at a leaf, we need to provide additional one to account for two corners if (count < 2) { MovingParticle* particle2 = factory->makeParticle(u->key, Initial, 0.0f); points.push_back(particle2); } //When this is the first node of the trace, the last one is extra unless this is also a leaf node. if (prev == NULL && count > 2) { MovingParticle* p = *(points.end() - 1); factory->inactivate(p); points.erase(points.end() - 1); } }
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; }