以前矩形波、のこぎり波を紹介しましたが、今回は三角波の作成方法を紹介します。



周期ごとの場合分けと、位相と周波数の考え方は以前紹介した矩形波やのこぎり波とほぼ一緒です。

では早速
サンプリング間隔:nInterval(ms)
データ数:nDataNum
振幅:dbAmp(dBやVolt等)
周波数:dbFrequency(Hz)
位相:dbPhase(度)
オフセット:dbOffset

三角波を作成してみます。


int nInterval // サンプリング間隔(ms)
double dbOffset // 縦軸オフセット(0点)
double dbAmp // 振幅(dB、電圧値等)
double dbFrequency // 周波数(Hz)
double dbPhase // 位相(度)

for( nDataCnt = 0; nDataCnt < nDataNum; nDataCnt++ )
{
nRemain = (int)( nInterval * nDataCnt - 1000 * dbPhase / 360 + 250 / dbFrequency ) % (int)( 1000 / dbFrequency );

if( -1000 <= nRemain && nRemain < -500/dbFrequency )

adWaveData[ nDataCnt ] = dbAmp / ( 250/dbFrequency ) * nRemain + dbOffset + 3 * dbAmp;

else if( -500/dbFrequency <= nRemain && nRemain < 0 )

adWaveData[ nDataCnt ] = (-1) * dbAmp / (250/dbFrequency) * nRemain + dbOffset - dbAmp;

else if( 0 <= nRemain && nRemain < 500/dbFrequency )

adWaveData[ nDataCnt ] = dbAmp / (250/dbFrequency) * nRemain + dbOffset - dbAmp;

else if( 500/dbFrequency <= nRemain && nRemain < 1000/dbFrequency )

adWaveData[ nDataCnt ] = (-1) * dbAmp / (250/dbFrequency) * nRemain + dbOffset + 3 * dbAmp;
}


さて、前回ののこぎり波は右上がりの一次式:y=ax+b(0今回は傾きが周期毎に+、-と変化しています。三角形が右上がり、左上がりの直線の形になってるからですね。
ですが、基本はy=ax+bの形の式です。
±dbAmp / ( 250 / dbFrequency ) が傾き±aの部分です。

nRemainが現在の横軸の点の位置(x)になります。
nDataCntがインクリメントするごとにサンプリング間隔毎に点が移動するので、
nInterval * nDataCnt(ms)になります。

更に位相ずれ分(横軸に平行移動)を考慮した部分が - 1000 * dbPhase / 360 になります。

全体を最終的に % (int)( 1000 / dbFrequency ) してる部分が作成したい波形の
周期を考慮した部分です。
これにより、nInterval * nDataCnt(ms)部分が周期(1000 / dbFrequency)を超えたらnRemainが0に戻ります。
この部分が周期関数を実現している部分になります。

さて、以前紹介した矩形波、のこぎり波には無かった、250 / dbFrequencyの部分ですが、
この波形の式は始まり(x=0)の値が最小値から始まった式になってます。よってsin波等と同じく
dbOffset値から始める為にx軸方向に平行移動している分になります。

矩形波、のこぎり波:
nRemain = (int)( nInterval * nDataCnt - 1000 * dbPhase / 360 ) % (int)( 1000 / dbFrequency );
三角波:
nRemain = (int)( nInterval * nDataCnt - 1000 * dbPhase / 360 + 250 / dbFrequency ) % (int)( 1000 / dbFrequency );

次にb:一次式のy切片の部分です。

dbOffsetは波形の縦軸方向中間位置を表し、波形全体を縦軸方向に平行移動させます。
場合分け毎全ての式において共通の部分です。
以下場合分け毎のy切片の説明です。

・-1000 < nRemain && nRemain < -500/dbFrequencyの時は
 右上がりの直線なので、y切片は dbOffset + 3 * dbAmp となります。

・500/dbFrequency < nRemain && nRemain < 1000/dbFrequencyの時は、
 右下がりの直線なので、y切片は dbOffset - 3 * dbAmp となります。

・-500/dbFrequency < nRemain && nRemain < 0 及び
 0 < nRemain && nRemain < 500/dbFrequency の時は隣り合う三角形同士境目(極小値)の部分なので、
 dbOffset - dbAmp となります。

では、また。