何かsin波に似てますね。カーブが無くなってギザギザになった波形です。
しかし、作成するには自分で計算式を組まないと作れないので結構やっかいです。

周期ごとの場合分けと、位相と周波数の考え方は以前紹介した矩形波やのこぎり波とほぼ一緒です。
では早速
サンプリング間隔:nInterval(ms)
データ数:nDataNum
振幅:dbAmp(dBやVolt等)
周波数:dbFrequency(Hz)
位相:dbPhase(度)
オフセット:dbOffset
三角波を作成してみます。データ数: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 = a x + b (0 < a) が連続しているだけでしたが、
今回は傾きが周期毎に+、-と変化しています。三角形が右上がり(左下がり)、左上がり(右下がり)の直線の形になってるからですね。
ですが、基本は y = a x + 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値(0点)から始める為にx軸方向に1/4周期平行移動している分になります。
矩形波、のこぎり波:
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 となります。
では、また。