<commit_before>#include "DefaultForce.h"
#include "ofxWWTweetParticle.h"
#include "ofxWWTweetParticleManager.h"

DefaultForce::DefaultForce(ofxWWTweetParticleManager& manager)
	:Force(manager)
	,should_hide_on(0)
	,hide_duration_millis(2800) // TODO add to settings
	,hide_force(58.0f) // TODO add to settings
{
	center.set(manager.simulationWidth * 0.5,manager.simulationHeight * 0.5);
}

bool DefaultForce::isReadyWithHiding() {
	return (ofGetElapsedTimeMillis() >= should_hide_on);
}

void DefaultForce::activateParticle(ofxWWTweetParticle& p) {
}

void DefaultForce::deactivateParticle(ofxWWTweetParticle& p) {
	p.static_force = (p.pos - center).normalize() * hide_force;
	p.setState(ofxWWTweetParticle::STATE_HIDING);
}

// called once when showing.
void DefaultForce::activate() {
	should_hide_on = ofGetElapsedTimeMillis() + hide_duration_millis; // TODO make setting
	vector<ofxWWTweetParticle>::iterator it = tweets.begin();
	while(it != tweets.end()) {
		ofxWWTweetParticle& p = (*it);
		p.force.y += (manager.tweetFlowSpeed + p.speedAdjust) * (1-p.clampedSelectionWeight);
		++it;
	}
}

// called once, when hiding.
void DefaultForce::deactivate() {
	should_hide_on = ofGetElapsedTimeMillis() + hide_duration_millis; // TODO make setting
	vector<ofxWWTweetParticle>::iterator it = tweets.begin();
	while(it != tweets.end()) {
		ofxWWTweetParticle& p = (*it);
		p.static_force = (p.pos - center).normalize() * hide_force;
		p.setState(ofxWWTweetParticle::STATE_HIDING);
		++it;
	}
}

// called when "active" mode
void DefaultForce::show() {
	size_t len = tweets.size();
	for(int i = 0; i < len; i++){
		ofxWWTweetParticle& tweet = tweets[i];
		if(tweet.isSearchTweet){
			continue;
		}
		
		tweets[i].force.y += (manager.tweetFlowSpeed + tweet.speedAdjust) * (1-tweet.clampedSelectionWeight);
	}
}

void DefaultForce::hide() {
	// repulse from selected search term.
	ofxWWSearchTerm selected_term;
	if(manager.getSearchTermManager().getSelectedSearchTerm(selected_term)) {
		center = selected_term.pos;
	}
	
	float now = ofGetElapsedTimeMillis();
	float diff = should_hide_on - now;
	float p = MAX(0, (diff / hide_duration_millis)); // TODO add to settings

	// repulse from 
	vector<ofxWWTweetParticle>::iterator it = tweets.begin();
	ofVec2f dir;
	float dist = 0;
	float dist_sq = 0;
	float f = 0;
	float rest = 2500; // TODO add to settings.
	float duration_influance = sin(p*HALF_PI);
	float flow_force = manager.tweetFlowSpeed * 2;
	while(it != tweets.end()) {
		ofxWWTweetParticle& tweet = (*it);
		tweet.dot_opacity = p;
		dir = (center - tweet.pos);
		dist = dir.length();
		f =  (dist-rest) * (0.03 * duration_influance); // TODO add to settings
		dir.normalize();
		dir *= f;
		tweet.force += dir;
		tweet.force.y += (flow_force + tweet.speedAdjust) * (1-tweet.clampedSelectionWeight);
		++it;
	}	
	
	// repulse from eachother.
	it = tweets.begin();
	vector<ofxWWTweetParticle>::iterator other_it ;
	while(it != tweets.end()) {
		other_it = it+1;
		ofxWWTweetParticle& a = *it;
		while(other_it != tweets.end()) {
			ofxWWTweetParticle& b = *other_it;
			dir = (b.pos-a.pos);
			dist_sq = dir.lengthSquared();
			f = 1.0/dist_sq;
			
			dir *= f * (60 * duration_influance);  // TODO add to settings
			a.force += dir;
			b.force -= dir;
			++other_it;
			
		}
		++it;
	}
}

<commit_msg>Added repulsion to particles when search term is selected.<commit_after>#include "DefaultForce.h"
#include "ofxWWTweetParticle.h"
#include "ofxWWTweetParticleManager.h"

DefaultForce::DefaultForce(ofxWWTweetParticleManager& manager)
	:Force(manager)
	,should_hide_on(0)
	,hide_duration_millis(2800) // TODO add to settings
	,hide_force(58.0f) // TODO add to settings
{
	center.set(manager.simulationWidth * 0.5,manager.simulationHeight * 0.5);
}

bool DefaultForce::isReadyWithHiding() {
	return (ofGetElapsedTimeMillis() >= should_hide_on);
}

void DefaultForce::activateParticle(ofxWWTweetParticle& p) {
}

void DefaultForce::deactivateParticle(ofxWWTweetParticle& p) {
	p.static_force = (p.pos - center).normalize() * hide_force;
	p.setState(ofxWWTweetParticle::STATE_HIDING);
}

// called once when showing.
void DefaultForce::activate() {
	should_hide_on = ofGetElapsedTimeMillis() + hide_duration_millis; // TODO make setting
	vector<ofxWWTweetParticle>::iterator it = tweets.begin();
	while(it != tweets.end()) {
		ofxWWTweetParticle& p = (*it);
		p.force.y += (manager.tweetFlowSpeed + p.speedAdjust) * (1-p.clampedSelectionWeight);
		++it;
	}
}

// called once, when hiding.
void DefaultForce::deactivate() {
	should_hide_on = ofGetElapsedTimeMillis() + hide_duration_millis; // TODO make setting
	vector<ofxWWTweetParticle>::iterator it = tweets.begin();
	while(it != tweets.end()) {
		ofxWWTweetParticle& p = (*it);
		p.static_force = (p.pos - center).normalize() * hide_force;
		p.setState(ofxWWTweetParticle::STATE_HIDING);
		++it;
	}
}

// called when "active" mode
void DefaultForce::show() {
	size_t len = tweets.size();
	for(int i = 0; i < len; i++){
		ofxWWTweetParticle& tweet = tweets[i];
		if(tweet.isSearchTweet){
			continue;
		}
		
		tweets[i].force.y += (manager.tweetFlowSpeed + tweet.speedAdjust) * (1-tweet.clampedSelectionWeight);
	}
}

void DefaultForce::hide() {
	// repulse from selected search term.
	ofxWWSearchTerm selected_term;
	if(manager.getSearchTermManager().getSelectedSearchTerm(selected_term)) {
		center = selected_term.pos;
	}
	
	float now = ofGetElapsedTimeMillis();
	float diff = should_hide_on - now;
	float p = MAX(0, (diff / hide_duration_millis)); // TODO add to settings

	// repulse from 
	vector<ofxWWTweetParticle>::iterator it = tweets.begin();
	ofVec2f dir;
	float dist = 0;
	float dist_sq = 0;
	float f = 0;
	float rest = 2500; // TODO add to settings.
	float duration_influance = sin(p*HALF_PI);
	float flow_force = manager.tweetFlowSpeed * 2;
	while(it != tweets.end()) {
		ofxWWTweetParticle& tweet = (*it);
		tweet.dot_opacity = p;
		dir = (center - tweet.pos);
		dist = dir.length();
		f =  (dist-rest) * (0.03 * duration_influance); // TODO add to settings
		dir.normalize();
		dir *= f;
		tweet.force += dir;
		tweet.force.y += (flow_force + tweet.speedAdjust) * (1-tweet.clampedSelectionWeight);
		++it;
	}	
	
	// repulse from eachother.
	it = tweets.begin();
	vector<ofxWWTweetParticle>::iterator other_it ;
	while(it != tweets.end()) {
		other_it = it+1;
		ofxWWTweetParticle& a = *it;
		while(other_it != tweets.end()) {
			ofxWWTweetParticle& b = *other_it;
			dir = (b.pos-a.pos);
			dist_sq = dir.lengthSquared();
			f = 1.0/dist_sq;
			if(f > 0.04) {
				dir *= f * (60 * duration_influance);  // TODO add to settings
				a.force += dir;
				b.force -= dir;
			}
				++other_it;
			
		}
		++it;
	}
}


{'fraction_non_alphanumeric': 0.14711164322059264, 'fraction_numerical': 0.010625561209218797, 'mean_word_length': 4.363563402889246, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1068543', 'n_tokens_mistral': 2662, 'n_tokens_neox': 2477, 'n_words': 492}