web-dev-qa-db-ja.com

C ++での正弦波の生成

一連のポイントを生成しようとしています。これをグラフとしてプロットすると、1サイクルの正弦波を表します。要件は次のとおりです。

  • 1サイクルの正弦波
  • 下限= 29491
  • 上限= 36043
  • ポイント数= 100
  • 振幅= 3276
  • ゼロオフセット= 32767

コード:

int main()
{
    ofstream outfile;
    outfile.open("data.dat",ios::trunc | ios::out);
    for(int i=0;i<100;i++)
    {
        outfile << int(3276*sin(i)+32767) << "\n";
    }
    outfile.close();
    return 0;
}

ポイントを生成してファイルに保存しています。これらのポイントをプロットすると、次のグラフが表示されます。

enter image description here

しかし、必要なのは1サイクルだけです。これどうやってするの?

4
Pradeep

正弦波 の式を取り入れます:

y(t) = A * sin(2 * PI * f * t + shift)

どこ:

A =振幅、ゼロからの関数のピーク偏差。
f =通常の周波数、振動数(サイクル)
t =時間
shift =位相シフト

だろう:

y[t] = AMPLITUDE * sin (2 * M_PI * 0.15 * t + 0) + ZERO_OFFSET;
                                   ^^^ f = 15 cycles / NUM_POINTS = 0.15 Hz

フルサイクルを1つにするには、y[0:t)からループします。ここで、tは、フルサイクル(つまり波長)をとるのにかかる時間またはポイント数です。

6
Joseph D.

1サイクルに100個のサンプルが必要なようですが、おそらくこれが必要です。

...
#define _USE_MATH_DEFINES
#include <math.h>
...
#define NB_OF_SAMPLES 100
...
  double angle = 0.0;
  for (int i = 0; i < NB_OF_SAMPLES; i++)
  {
    outfile << int(3276 * sin(angle) + 32767) << "\n";
    angle += (2 * M_PI) / NB_OF_SAMPLES;
  }
...

以上:

#define NB_OF_SAMPLES 100
#define OFFSET        3276
#define AMPLITUDE     32767

...
  double angle = 0.0;
  for (int i = 0; i < NB_OF_SAMPLES; i++)
  {
    outfile << int(AMPLITUDE * sin(angle) + OFFSET) << "\n";
    angle += (2 * M_PI) / NB_OF_SAMPLES;
  }
...
3
Jabberwocky

数学正弦関数 std :: sin はラジアンで引数を取ります:

arg-ラジアンで角度を表す、浮動小数点型または整数型の値

1サイクルと100ポイントが必要な場合、1サイクルに2piラジアンがあることがわかっているので、次のようなものが必要です。

double rads;
for(int i=1;i<=100;i++)
{
    rads = 2.0*M_PI*i/100;
    // your expression in terms of std::sin(rads)
}

万が一、コンパイラ/ライブラリのM_PIがすぐに使用できない場合は、 here を調べて、フラグを使用できるようにします。

触れられていないことの1つは、生成する必要がある正確な間隔です。閉じた間隔[0,2pi]が必要な場合は、ステップサイズを調整する必要があります。私はハーフオープン間隔(0,2pi)を指定し、@ Michael Walzは他のハーフオープン間隔[0,2pi]を指定しました。

0
Paul Floyd

Forループを0から2(pi)に反復するように変更する必要があります。これが正弦波の1サイクルです。また、ループカウンターを整数ではなくdoubleに変更し、代わりに0.1または何かをインクリメントすることもできます。 WolframAlpha.comからのスクリーンショット

0
IronMonkey

完全なサイクルは360度で構成されます。必要なサンプルは100です。
そのため、ステップサイズは3.6です

int main()
{
    ofstream outfile;
    outfile.open("data.dat",ios::trunc | ios::out);
    for(int i=0;i<101;i++)
    {
        float rads = M_PI/180;
        outfile << (float)(3276*sin(3.6*i*rads)+32767) << endl;
    }
    outfile.close();
    return 0;
}

サンプル数が200の場合、ステップサイズ360/200 = 1.8

int main()
{
    ofstream outfile;
    outfile.open("data.dat",ios::trunc | ios::out);
    for(int i=0;i<201;i++)
    {
        float rads = M_PI/180;
        outfile << (float)(3276*sin(1.8*i*rads)+32767) << endl;
    }
    outfile.close();
    return 0;
}

出力:

enter image description here

0
Pradeep