not good but great

プログラミング、アート、映画・本の感想について書きます。

マウスドラッグするとパーティクルが集まる


マウスドラッグするとパーティクルが集まってきます。

code

void vectorField::draw(){
    float fx,fy;
    for (int i = 0; i < field.size(); i++) {
        //グリッド上の点
        fx = field[i].x;
        fy = field[i].y;
        
        //力をリセット
        fieldForce[i].set(0,0);
        
        //方向ベクトルを作成
        ofVec2f directionVec = mousePoint - field[i];
        //単位ベクトルにする
        directionVec.normalize();
        //受ける力
        float strength = 30;
        float strongness = strength * (1.0f - (distance[i] / radius));
        
        //色
        ofSetColor(0, 200, 0);
        if(distance[i] < radius){
            ofCircle(fx + directionVec.x * strongness, fy + directionVec.y * strongness, 1 + strongness / 100);
            //力を保存
            fieldForce[i].set(directionVec.x * strongness, directionVec.y * strongness);
            
        }else{
            ofCircle(field[i].x, field[i].y, 1);
        }
    }
}

力を入れるベクタ配列を用意

緑のグリッドを描画したあとに、その緑の点にかかる力をfieldForceというベクタ配列に保存します。

ofVec2f vectorField::getForce(float posX, float posY){
    //白いパーティクルの位置ベクトル
    ofVec2f pa;
    pa.set(posX,posY);
    
    //受ける力のベクトル
    ofVec2f frc;
    frc.set(0,0);
    //画面の大きさに対しての相対位置
    float xPct = posX / (float)screenWidth;
    float yPct = posY / (float)screenHeight;
    float radiusPct	= radius / (float)screenWidth;
    
    //横から何番目の緑のベクトルか
    int fieldPosX = (int)(xPct * fieldRow);
    //縦から何番目の緑のベクトルか
    int fieldPosY = (int)(yPct * fieldCol);
    
    //一番近いベクトルのインデックス
    int pos = fieldPosX + fieldPosY * fieldRow;
    
    frc.x = fieldForce[pos].x * 0.005;
    frc.y = fieldForce[pos].y * 0.005;
    
    
    return frc;
}

マウスポインタから一番近い緑の点を探します。その緑の点のインデックス番号「pos」を使って、その点にかかっている力をfieldForceから取得します。そしてそれを定義したfrcに加算し、returnしています。

今回は力を受けて中心で止まらずに、力を受け続けています。これを中心で止めることをまたやってみようと思います。