//------------------------------------------------------------------ void seraParticle::update(){ ofPoint attractPt(mahoPos[1].x, mahoPos[1].y); frc = attractPt-pos; frc.normalize(); vel *= drag; vel += frc * seraParticleKasokuAmt; pos += vel; }
void demoParticle::choca( ) { ofPoint attractPt(ofGetMouseX(), ofGetMouseY()); frc = attractPt-pos; //obtiene la distancia float dist = frc.length(); frc.normalize(); // se repelen los puntos serca del mouse if( dist < 90 ){ pos += -frc * 0.1; } }
//------------------------------------------------------------------ void demoParticle::update(){ // 1 - APPLY THE FORCES BASED ON WHICH MODE WE ARE IN // 1 - 加载的力取决于我们选择何种模式 if( mode == PARTICLE_MODE_ATTRACT ){ ofPoint attractPt(ofGetMouseX(), ofGetMouseY()); frc = attractPt-pos; // we get the attraction force/vector by looking at the mouse pos relative to our pos // 粒子获得的引力是通过计算鼠标位置和粒子位置的关系得到的 frc.normalize(); // by normalizing we disregard how close the particle is to the attraction point // 通过初始化力,我们忽略了粒子和吸引点之间的距离。 vel *= drag; // apply drag // 用拖拽 vel += frc * 0.6; // apply force // 用力 } else if( mode == PARTICLE_MODE_REPEL ){ ofPoint attractPt(ofGetMouseX(), ofGetMouseY()); frc = attractPt-pos; // let get the distance and only repel points close to the mouse // 击退离鼠标够近的粒子 float dist = frc.length(); frc.normalize(); vel *= drag; if( dist < 150 ){ vel += -frc * 0.6; // notice the frc is negative // 注意,力是相反的 }else{ //if the particles are not close to us, lets add a little bit of random movement using noise. this is where uniqueVal comes in handy. //如果粒子不够靠近,我们可以用噪点制造一些随机移动。这就是为什么我们前面创建了一个随机数字,它让每个粒子的移动略微不同。 frc.x = ofSignedNoise(uniqueVal, pos.y * 0.01, ofGetElapsedTimef()*0.2); frc.y = ofSignedNoise(uniqueVal, pos.x * 0.01, ofGetElapsedTimef()*0.2); vel += frc * 0.04; } } else if( mode == PARTICLE_MODE_NOISE ){ /* lets simulate falling snow the fake wind is meant to add a shift to the particles based on where in x they are we add pos.y as an arg so to prevent obvious vertical banding around x values - try removing the pos.y * 0.006 to see the banding 下面,我们会用粒子模拟下雪的效果 为了模拟风对雪的影响,我们会在x轴上加入一个移动效果 提供y坐标为了不给x坐标过多的影响力 */ float fakeWindX = ofSignedNoise(pos.x * 0.003, pos.y * 0.006, ofGetElapsedTimef() * 0.6); frc.x = fakeWindX * 0.25 + ofSignedNoise(uniqueVal, pos.y * 0.04) * 0.6; frc.y = ofSignedNoise(uniqueVal, pos.x * 0.006, ofGetElapsedTimef()*0.2) * 0.09 + 0.18; vel *= drag; vel += frc * 0.4; // we do this so as to skip the bounds check for the bottom and make the particles go back to the top of the screen // 如果往下移动时发现跨过边界,就屏幕下消失然后从上面出现 if( pos.y + vel.y > ofGetHeight() ){ pos.y -= ofGetHeight(); } } else if( mode == PARTICLE_MODE_NEAREST_POINTS ){ if( attractPoints ){ // 1 - find closest attractPoint // 1 - 寻找周围最接近的粒子 ofPoint closestPt; int closest = -1; float closestDist = 9999999; for(unsigned int i = 0; i < attractPoints->size(); i++){ float lenSq = ( attractPoints->at(i)-pos ).lengthSquared(); if( lenSq < closestDist ){ closestDist = lenSq; closest = i; } } // 2 - if we have a closest point - lets calcuate the force towards it // 2 - 计算力对closetPt产生的力量 if( closest != -1 ){ closestPt = attractPoints->at(closest); float dist = sqrt(closestDist); // in this case we don't normalize as we want to have the force proportional to distance // 不要规范为0至1,力量必须相对一距离 frc = closestPt - pos; // 别忘了乘以拖拽 vel *= drag; // lets also limit our attraction to a certain distance and don't apply if 'f' key is pressed // 设置吸引力的底线,如果按下'f'就放弃 if( dist < 300 && dist > 40 && !ofGetKeyPressed('f') ){ vel += frc * 0.003; }else{ // if the particles are not close to us, lets add a little bit of random movement using noise. this is where uniqueVal comes in handy. // 距离够远的话可以考虑添加一点随机行为 frc.x = ofSignedNoise(uniqueVal, pos.y * 0.01, ofGetElapsedTimef()*0.2); frc.y = ofSignedNoise(uniqueVal, pos.x * 0.01, ofGetElapsedTimef()*0.2); vel += frc * 0.4; } } } } // 2 - UPDATE OUR POSITION // 2 - 更新位置 pos += vel; // 3 - (optional) LIMIT THE PARTICLES TO STAY ON SCREEN // we could also pass in bounds to check - or alternatively do this at the ofApp level // 防止粒子走出屏幕,碰到边界时就立刻改变方向 if( pos.x > ofGetWidth() ){ pos.x = ofGetWidth(); vel.x *= -1.0; }else if( pos.x < 0 ){ pos.x = 0; vel.x *= -1.0; } if( pos.y > ofGetHeight() ){ pos.y = ofGetHeight(); vel.y *= -1.0; } else if( pos.y < 0 ){ pos.y = 0; vel.y *= -1.0; } }
//------------------------------------------------------------------ void demoParticle::update(ofPoint extraAttractor){ //1 - APPLY THE FORCES BASED ON WHICH MODE WE ARE IN if( mode == PARTICLE_MODE_ATTRACT ){ /* ofVec2f attractPt(ofGetMouseX(), ofGetMouseY()); frc = attractPt-pos; // we get the attraction force/vector by looking at the mouse pos relative to our pos frc.normalize(); //by normalizing we disregard how close the particle is to the attraction point vel *= drag; //apply drag vel += frc * 0.6; //apply force */ ofPoint attractPt = extraAttractor; frc = attractPt-pos; // we get the attraction force/vector by looking at the mouse pos relative to our pos frc.normalize(); //by normalizing we disregard how close the particle is to the attraction point vel *= drag; //apply drag vel += frc * 0.6; //apply force } else if( mode == PARTICLE_MODE_REPEL ){ ofVec2f attractPt(ofGetMouseX(), ofGetMouseY()); frc = attractPt-pos; //let get the distance and only repel points close to the mouse float dist = frc.length(); frc.normalize(); vel *= drag; if( dist < 150 ){ vel += -frc * 0.6; //notice the frc is negative }else{ //if the particles are not close to us, lets add a little bit of random movement using noise. this is where uniqueVal comes in handy. frc.x = ofSignedNoise(uniqueVal, pos.y * 0.01, ofGetElapsedTimef()*0.2); frc.y = ofSignedNoise(uniqueVal, pos.x * 0.01, ofGetElapsedTimef()*0.2); vel += frc * 0.04; } } else if( mode == PARTICLE_MODE_NOISE ){ //lets simulate falling snow //the fake wind is meant to add a shift to the particles based on where in x they are //we add pos.y as an arg so to prevent obvious vertical banding around x values - try removing the pos.y * 0.006 to see the banding float fakeWindX = ofSignedNoise(pos.x * 0.003, pos.y * 0.006, ofGetElapsedTimef() * 0.6); frc.x = fakeWindX * 0.25 + ofSignedNoise(uniqueVal, pos.y * 0.04) * 0.6; frc.y = ofSignedNoise(uniqueVal, pos.x * 0.006, ofGetElapsedTimef()*0.2) * 0.09 + 0.18; vel *= drag; vel += frc * 0.4; //we do this so as to skip the bounds check for the bottom and make the particles go back to the top of the screen if( pos.y + vel.y > ofGetHeight() ){ pos.y -= ofGetHeight(); } } else if( mode == PARTICLE_MODE_NEAREST_POINTS ){ if( attractPoints ){ //1 - find closest attractPoint ofVec2f closestPt; int closest = -1; float closestDist = 9999999; for(unsigned int i = 0; i < attractPoints->size(); i++){ float lenSq = ( attractPoints->at(i)-pos ).lengthSquared(); if( lenSq < closestDist ){ closestDist = lenSq; closest = i; } } //2 - if we have a closest point - lets calcuate the force towards it if( closest != -1 ){ closestPt = attractPoints->at(closest); float dist = sqrt(closestDist); //in this case we don't normalize as we want to have the force proportional to distance frc = closestPt - pos; vel *= drag; //lets also limit our attraction to a certain distance and don't apply if 'f' key is pressed if( dist < 300 && dist > 40 && !ofGetKeyPressed('f') ){ vel += frc * 0.003; }else{ //if the particles are not close to us, lets add a little bit of random movement using noise. this is where uniqueVal comes in handy. frc.x = ofSignedNoise(uniqueVal, pos.y * 0.01, ofGetElapsedTimef()*0.2); frc.y = ofSignedNoise(uniqueVal, pos.x * 0.01, ofGetElapsedTimef()*0.2); vel += frc * 0.4; } } } } //2 - UPDATE OUR POSITION pos += vel; //3 - (optional) LIMIT THE PARTICLES TO STAY ON SCREEN //we could also pass in bounds to check - or alternatively do this at the ofApp level if( pos.x > ofGetWidth() ){ pos.x = ofGetWidth(); vel.x *= -1.0; }else if( pos.x < 0 ){ pos.x = 0; vel.x *= -1.0; } if( pos.y > ofGetHeight() ){ pos.y = ofGetHeight(); vel.y *= -1.0; } else if( pos.y < 0 ){ pos.y = 0; vel.y *= -1.0; } }