0

時間とともに変化する 1000 行以上の正弦波データがあり、それを処理言語で視覚化したいと考えています。私の目的は、長方形の [height/2] の中央から時間とともに正弦波を描くアニメーションを作成することです。また、その波の 1 秒周期のみを表示したいと考えています。つまり、1 秒後に最初の座標が消えるということです。

どうすればそれを達成できますか? ありがとう

サンプルデータ :

 TIME   X   Y
0.1333  0   0
0.2666  0.1 0.0999983333
0.3999  0.2 0.1999866669
0.5332  0.3 0.299955002
0.6665  0.4 0.3998933419
0.7998  0.5 0.4997916927
0.9331  0.6 0.5996400648
1.0664  0.7 0.6994284734
4

1 に答える 1

1

これを達成する方法は、このプロジェクトをタスクに分割することです。

  1. データの読み込みと解析
  2. 更新時間とレンダリング データ

パート 1 がスムーズに進むようにするには、最初にデータの解析が容易であることを確認するのがおそらく最善です。サンプル データは表/スプレッドシートのように見えますが、標準の区切り文字 (コンマやタブなど) でフォーマットされていません。space解析するときに何かをいじることができますが、たとえばセパレーターとして使用する予定がある場合は、最初にクリーンなデータを使用することをお勧めします。

 TIME  X   Y
0.1333 0.0 0
0.2666 0.1 0.0999983333
0.3999 0.2 0.1999866669
0.5332 0.3 0.299955002
0.6665 0.4 0.3998933419
0.7998 0.5 0.4997916927
0.9331 0.6 0.5996400648
1.0664 0.7 0.6994284734

それが完了したら、loadStrings()を使用してデータをロードし、split()を使用して行を 3 つの要素に分割し、文字列から浮動小数点数に変換できます。

使用する値を取得したら、それらを保存できます。それぞれがロードされたデータからフィールドを保持する 3 つの配列を作成するか (すべての X 値に対して 1 つ、すべての Y 値に対して 1 つ、すべての時間値に対して 1 つ)、PV​​ectorオブジェクトの単一の配列をごまかして使用することができます。PVector は 3D 数学/線形代数を対象としていますが、2D 座標があるため、時間を 3 番目の「次元」/コンポーネントとして格納できます。

パート 2 は主に時間に基づく更新を中心に展開します。ここでmillis()が役に立ちます。更新の間に経過した時間を確認でき、それが特定の (遅延) 値よりも大きい場合は、(フレーム/データ行インデックスの) 別の更新の時間です。

心配する必要がある最後の部分は、データを画面にレンダリングすることです。幸いなことに、サンプル データでは、座標が (0.0 から 1.0 の間で) 正規化されているため、(単純な乗算を使用して) スケッチの寸法に簡単にマッピングできます。それ以外の場合は、map()関数が便利です。

上記を説明するためのスケッチを次に示します。data.csv は、上記の書式設定されたサンプル データを含むテキスト ファイルです。

PVector[] frames;//keep track of the frame data(position(x,y) and time(store in PVector's z property))
int currentFrame = 0,totalFrames;//keep track of the current frame and total frames from the csv
int now, delay = 1000;//keep track of time and a delay to update frames

void setup(){
  //handle data
  String[] rows = loadStrings("data.csv");//load data
  totalFrames = rows.length-1;//get total number of lines (-1 = sans the header)
  frames = new PVector[totalFrames];//initialize/allocate frame data array 
  for(int i = 1 ; i <= totalFrames; i++){//start parsing data(from 1, skip header)
    String[] frame = rows[i].split(" ");//chop each row into 3 strings(time,x,y)
    frames[i-1] = new PVector(float(frame[1]),float(frame[2]),float(frame[0]));//parse each row(not i-1 to get back to 0 index) and how the PVector's initialized 1,2,0 (x,y,time)
  }
  now = millis();//initialize this to keep track of time
  //render setup, up to you
  size(400,400);smooth();fill(0);strokeWeight(15);
}
void draw(){
  //update
  if(millis() - now >= delay){//if the amount of time between the current millis() and the last time we updated is greater than the delay (i.e. every 'delay' ms)
    currentFrame++;//update the frame index
    if(currentFrame >= totalFrames) currentFrame = 0;//reset to 0 if we reached the end
    now = millis();//finally update our timer/stop-watch variable
  }
  PVector frame = frames[currentFrame];//get the data for the current frame
  //render
  background(255);
  point(frame.x * width,frame.y * height);//draw
  text("frame index: " + currentFrame + " data: " + frame,mouseX,mouseY);
}

必要な追加のメモがいくつかあります。

  1. 1秒後に次の座標に移動するとおっしゃいました。サンプル データで確認できることから、1 秒あたり 8 回の更新があるため、1000/8 の方がうまくいくでしょう。ただし、タイミングをどのように処理するかはあなた次第です。
  2. あなたのフルセットには正弦波の動きのデータが含まれていると思います。私は完全な座標にマッピングしましたが、draw()ループのレンダリング部分では、好きなようにマッピングできます (たとえば、高さ/2 のオフセットを含むなど)。また、正弦波に慣れていない場合は、次の処理リソースを参照してください: Daniel Shiffman の SineWave サンプルIra Greenberg の trig チュートリアル
于 2013-01-14T00:59:22.447 に答える