0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CERN ROOT (C++) グラフ作成 (3) for とsleepを使ってアニメーション (sinの進行波, sin cos描画)

Posted at

概要

通常グラフのアニメーションはアニメーションgifが一般的であるが、長いアニメーションはファイルサイズの大きくなり、gifファイルを作成するのも少し時間を要する。通常のアプリケーションのようにGUI上で簡単にアニメーションができたら良いなと思っていた。
CERN ROOTでは描画の間にSleepを入れるだけで簡単にアニメーションになる。CERN ROOTを本格的に覚えようと思った動機でもある。

実行環境

sw_vers
ProductName:		macOS
ProductVersion:		14.6.1
BuildVersion:		23G93

root --version
ROOT Version: 6.32.06
Built for macosxarm64 on Sep 21 2024, 18:21:53
From tags/6-32-06@6-32-06

sinの進行波のアニメーション

sinの進行波は次の式で表される
$$
A\sin(kx-\omega t)
$$
$k$:波数 $\omega$: 角振動数

sin_wave.C
void sin_wave() { 
    constexpr double timer = 100;
    constexpr double y_max = 1.5;
    auto canvas = new TCanvas("canvas");
    canvas->SetGrid();
    auto gr = new TF1("wave", "TMath::Sin([0]*x - [1]*[2])", 0,10);
    double t = 0;
    double k = 2;
    double w = 1;
    gr->SetParameters(k, w, t);
    gr->SetTitle("sin (kx - #omega t)");
    gr->SetMaximum(y_max);   //y軸の最大値
    gr->SetMinimum(-y_max);  //y軸の最小値  
    gr->Draw();
    canvas->ModifiedUpdate();
    for(int i = 0; i < 100 && !gSystem->ProcessEvents(); i++) {
        gSystem->Sleep(timer);
        t += 0.2;
        gr->SetParameter(2,t);
        canvas->ModifiedUpdate();
    }
}

TF1の第2引数が進行波の計算式で、[0]が波数、[1]が角振動数、[2]が時間でgr->SetParameters(k,w,t)で具体的な値をセットしています。
forループ内のgr->SetParameter(2,t)は時間だけが変化するので計算式の[2]だけを変更します。
gSystem->Sleepはミリ秒です。gSystem->ProcessEventsは無くても問題なく動作します。

実行するが、これはGUI上のアニメーションなのでアニメーションをここで表示することはできない。なので、終了時の画面のスクショを添付する。

root [0] .x sin_wave.C
root [1]

途中で止めたいときはROOT上でCTRL+Cを打鍵します。

2024-11-02 15.33.28.png

PyROOTバージョン

sin_wave.py
import ROOT as RT

timer = 100
y_max = 1.5
canvas = RT.TCanvas("canvas")
canvas.SetGrid()

gr = RT.TF1("wave", "TMath::Sin([0]*x - [1]*[2])", 0,10)
t = 0.0
k = 3.0
w = 1.0
gr.SetParameters(k, w, t)
gr.SetTitle("sin (#kappa x - #omega t)")
gr.SetMaximum(y_max)
gr.SetMinimum(-y_max)    
gr.Draw()
canvas.ModifiedUpdate()
for i in range(100):
    if RT.gSystem.ProcessEvents():
        break
    RT.gSystem.Sleep(timer)
    t += 0.2
    gr.SetParameter(2,t)
    canvas.ModifiedUpdate()

実行する

source thisroot.sh

python3 -i sin_wave.py
>>> 

-iオプションは実行終了後Pythonが終了してしまうと、実行終了時が画面も消えてしまうので、-iオプションでPythonを終わらせないようにします。 スクショは同じなので省略します。

sin,cosの重ねグラフを徐々に描画するアニメーション

CERN ROOT (C++) グラフ作成 (1) sin,cosのグラフの重ね表示で描画したsin,cosの重ねグラフの描画を1マーカ毎に描画するアニメーション。

sincos_anime.C
void sincos_anime() {
    auto canvas = new TCanvas("canvas");
    auto gr = new TGraph();
    auto gr2 = new TGraph();
    gr->SetMarkerStyle(20);
    gr->SetMarkerColor(2);
    gr->SetMinimum(-1.1);  //y軸の最小値
    gr->SetMaximum(1.1);   //y軸の最大値
    gr->GetXaxis()->SetLimits(0,4); //x軸の範囲
    gr->AddPoint(0, TMath::Sin(0)); 
    gr->Draw("apc");

    gr2->SetMarkerColor(4);
    gr2->SetMarkerStyle(40);
    gr2->AddPoint(0, TMath::Cos(0));
    gr2->Draw("pc");

    canvas->ModifiedUpdate();
    for(int i = 1; i < 100 && !gSystem->ProcessEvents(); i++) {
        gSystem->Sleep(100);
        float x = 0.04 * i;
        float ys = TMath::Sin(x * 4);
        float yc = TMath::Cos(x * 4);
        gr->AddPoint(x, ys); 
        gr2->AddPoint(x, yc);
        gr->SetMinimum(-1.1);
        gr->SetMaximum(1.1);
        gr->GetXaxis()->SetLimits(0,4);
        canvas->ModifiedUpdate();
    }
}

CERN ROOT (C++) グラフ作成 (1) sin,cosのグラフの重ね表示のときとは異なり、プロットする点をAddPointを使っています。

2024-11-02 18.16.47.png

実際に実行すると赤い点などが1個ずつ描画されるアニメーションなっています。

PyROOTバージョン

PyROOTでは以下のようなコードになります。スクショは省略します。

sincos_anime.py
import ROOT as RT

canvas = RT.TCanvas("canvas")
gr = RT.TGraph()
gr2 = RT.TGraph()
gr.SetMarkerStyle(20)
gr.SetMarkerColor(2)
gr.SetMinimum(-1.1)
gr.SetMaximum(1.1)
gr.GetXaxis().SetLimits(0,4)
gr.AddPoint(0, RT.TMath.Sin(0)) 
gr.Draw("apc")

gr2.SetMarkerColor(4)
gr2.SetMarkerStyle(40)
gr2.AddPoint(0, RT.TMath.Cos(0))
gr2.Draw("pc")

canvas.ModifiedUpdate()
for i in range(1,100):
    if RT.gSystem.ProcessEvents():
       break
    RT.gSystem.Sleep(100)
    x = 0.04 * i
    ys = RT.TMath.Sin(x * 4)
    yc = RT.TMath.Cos(x * 4)
    gr.AddPoint(x, ys) 
    gr2.AddPoint(x, yc)
    gr.SetMinimum(-1.1)
    gr.SetMaximum(1.1)
    gr.GetXaxis().SetLimits(0,4)
    canvas.ModifiedUpdate()

関連

終わりに

ここでは実際のアニメーションを見せられないのが残念ですが、興味にある方はぜひCERN ROOTで実行してみてください。 次回は簡単な物理シミュレーションのアニメーションを予定しています。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?