void apply(bool simulate_time = false) { for(map<NodeID,Node>::iterator it = graph.nodes_begin(); it != graph.nodes_end(); it++) { Node& n1 = it->second; if (!n1.visible()) continue; constrain_to_field(n1); for(map<NodeID,Node>::iterator it2 = graph.nodes_begin(); it2 != graph.nodes_end(); it2++) { Node& n2 = it2->second; if (n1.oid() == n2.oid()) continue; if (!n2.visible()) continue; float distance = n1.pos().distance(n2.pos()); if (distance == 0) { n2.pos().x += 0.1; } Vec2f connection(n2.pos().x-n1.pos().x, n2.pos().y-n1.pos().y); if (n1.parent_of_visible(n2.oid())) { turn(n1, n2); n1.velocity() += connection.normal()*attract(n1, n2); n2.velocity() -= connection.normal()*attract(n1, n2); } n1.velocity() += connection.normal()*repulse(n1, n2); } } int elapsed_ms = clock.getElapsedTime().asMilliseconds(); clock.restart(); if (simulate_time) elapsed_ms = 100; for(map<NodeID,Node>::iterator it = graph.nodes_begin(); it != graph.nodes_end(); it++) { Node& n1 = it->second; float max = 500; if (n1.velocity().length()>max) n1.velocity() = n1.velocity().normal()*max; n1.velocity() *= damping; n1.pos() += n1.velocity()*((float)(elapsed_ms/30.0)); if (n1.label() == "index") { n1.pos().x = 1000; n1.pos().y = graph.index_pos; continue; } else if (n1.oid().type == INDEX_ENTRY) { n1.pos().x = graph.right_border+10; n1.pos().y = graph.index_pos+atoi(n1.oid().name.c_str())*30; } } }
void Dots::update() { for(unsigned int i = 0; i < particles.size(); i++){ particles[i].neighbors.clear(); } for(unsigned int i = 0; i < particles.size(); i++){ float dt = ofGetLastFrameTime(); particles[i].position += particles[i].velocity * dt; for (unsigned int j = i + 1; j < particles.size(); j++) { float dist = particles[i].position.distance(particles[j].position); if (dist < plexusDistance) { particles[i].neighbors.push_back(&particles[j]); attract(particles[i], particles[j]); } } if (abs(getPosition().distance(particles[i].position)) > 500) { particles[i].velocity -= particles[i].position.normalized() * 10; } } }
void Connections::fullAttract() { calcComps(); double spfac = 1.3; double spnow = 1; int i = start_i; for (int cycle = 0; cycle < numcycles; cycle++) { int sps = qRound(spnow); subdivide(sps); qDebug() << "starting " << i << " iterations with c_thr:" << c_thr << "segments: " << edges.first()->points.length()-1; for (int j = 0; j<i; j++) { //qDebug() << j; attract(); } i--; spnow *= spfac; } //for further subdivision without attraction /*for (int i=1; i<3; i++){ subdivide(qRound(spnow)+i); qDebug() << "number of subd. points: " << qRound(spnow)+i; }*/ }
//-------------------------------------------------------------- // MARK: UPDATE //-------------------------------------------------------------- void testApp::update(){ // -------------------------------------------- // DATA UPDATE // XML update > data update if(xmlThread.isAvailable() && !bRandomizeParticles) { data.getResultsFromBuffer(xmlThread.getXML()); // if it is starting, load the first batch if(!hasInitiated) { hasInitiated = true; bResetData = true; // else, if it already started, add new particles (if it is the case) } else { if(data.getNewStreetPositives() != 0 || data.getNewStreetNeutrals() != 0 || data.getNewStreetNegatives() != 0 || data.getNewNeighborhoodPositives() != 0 || data.getNewNeighborhoodNeutrals() != 0 || data.getNewNeighborhoodNegatives() != 0 || data.getNewCityPositives() != 0 || data.getNewCityNeutrals() != 0 || data.getNewCityNegatives() != 0) { bResetData = true; } } } // reset the particles arrays, if it's the case if(bResetData) { // check if the new data should be randomized if(bRandomizeParticles) { // generating random values int delta = iMaxRandomParticles * ((100.0-iDeltaRandomParticles)/100.0); data.generateRandomValues(delta, iMaxRandomParticles); } bResetData = false; initPaths(); initParticles(); } // -------------------------------------------- // KINECT UPDATE kinect.updateThreshPar(iFarThreshold, iNearThreshold); kinect.updateBlobPar(iMinBlobSize, iMaxBlobSize, iMaxNumBlobs); if(!bLockKinTilt) { kinect.setKinTiltAngle(false, fKin1TiltAngle); kinect.setKinTiltAngle(true, fKin2TiltAngle); } kinect.update(); // -------------------------------------------- // ATTRACTORS FROM BLOBS // variables to calculate the average attractor float sumx[3] = {0.0, 0.0, 0.0}; float sumy[3] = {0.0, 0.0, 0.0}; int counter[3] = {0, 0, 0}; // destroy dead attractors for(map<int, Attractor>::iterator it = attractors.begin(); it != attractors.end(); it++) { if( kinect.foundBlobsMap.find((*it).first) == kinect.foundBlobsMap.end() ) { // get attractor Attractor a = (*it).second; // and check if it's time to die if ( time(0) - a.bornTime > a.lifeTime ) { attractors.erase(it); } else { // if attractor is located in the first panel - the street panel if(a.location.x < FBO_W / 3) { sumx[0] += a.location.x; sumy[0] += a.location.y; counter[0]++; } // or if attractor is located in the second panel - the neighborhood panel else if(a.location.x < FBO_W / 3 * 2) { sumx[1] += a.location.x; sumy[1] += a.location.y; counter[1]++; } // or if attractor is located in the third panel - the city panel else { sumx[2] += a.location.x; sumy[2] += a.location.y; counter[2]++; } } } } // update and add attractors for(int i = 0; i < kinect.activeBlobsIds.size(); i++) { // search for the key on the map int theKey = kinect.activeBlobsIds[i]; ofxBlob b = kinect.foundBlobsMap[theKey]; map<int, Attractor>::iterator it = attractors.find(theKey); // if it's already on it, update attractor if( it != attractors.end() ) { // inverting blob x float x = ofMap(b.centroid.x, 1.0f, 0.0f, 0.0f, 1.0f); attractors[theKey].location.set(x * FBO_W, b.centroid.y * FBO_H); } // else, add attractor to the map else { // inverting blob x float x = ofMap(b.centroid.x, 1.0f, 0.0f, 0.0f, 1.0f); // add attractor to the map Attractor attract(ofVec2f(x * FBO_W, b.centroid.y * FBO_H), fAttractorLife); attractors[theKey] = attract; } // if attractor is located in the first panel - the street panel if(attractors[theKey].location.x < FBO_W / 3) { sumx[0] += attractors[theKey].location.x; sumy[0] += attractors[theKey].location.y; counter[0]++; } // or if attractor is located in the second panel - the neighborhood panel else if(attractors[theKey].location.x < FBO_W / 3 * 2) { sumx[1] += attractors[theKey].location.x; sumy[1] += attractors[theKey].location.y; counter[1]++; } // or if attractor is located in the third panel - the city panel else { sumx[2] += attractors[theKey].location.x; sumy[2] += attractors[theKey].location.y; counter[2]++; } } // if there are attractors in the first panel - the street panel, // set the panel average attractor if(counter[0] > 0) { doStreetPanelAttraction = true; attractorStreetPanel.setLocation(ofVec2f(sumx[0]/(float)counter[0], sumy[0]/(float)counter[0])); } else { doStreetPanelAttraction = false; } // if there are attractors in the second panel - the neighborhood panel, // set the panel average attractor if(counter[1] > 0) { doNeighborhoodPanelAttraction = true; attractorNeighborhoodPanel.setLocation(ofVec2f(sumx[1]/(float)counter[1], sumy[1]/(float)counter[1])); } else { doNeighborhoodPanelAttraction = false; } // if there are attractors in the third panel - the city panel, // set the panel average attractor if(counter[2] > 0) { doCityPanelAttraction = true; attractorCityPanel.setLocation(ofVec2f(sumx[2]/(float)counter[2], sumy[2]/(float)counter[2])); } else { doCityPanelAttraction = false; } }