/**
* @brief 波表压缩算法
* @param 原波形数据
* @param 原波形长度
* @param 压缩后的波形数据
* @param 压缩的波形长度
*/
void AwgGuiWaveformWidget::waveCompressAlgorithm(u16 *pu16Source, u32 u32SourceNum, u16 *pu16Des, u32 u32DesNum)
{
u32 u32MaxPos, u32MinPos;
u16 u16Dot[4];
// 极值结构体
ExtremumValueStru strExtremum;
// 临时数据压缩数据
f32 *pf32TempDot;
pf32TempDot = (f32 *)malloc(u32DesNum * 2 * sizeof(f32));
// 先将原波形数据压缩成(u32DesNum * 2 - 2)个点
u32 u32CompressNumTemp = u32DesNum * 2 - 2;
// 计算压缩倍率
f32 f32Multiple = (f32)u32SourceNum / (f32)u32CompressNumTemp * 2;
// 计算循环次数
u32 u32Cycle = u32CompressNumTemp / 2;
u32 k = 0;
for (u32 i = 0; i < u32Cycle; i ++)
{
// 查找指定长度的最大值、最小值
if (i == (u32Cycle - 1))
{
this->findExtremum(&pu16Source[(u32)(f32Multiple * i)], (u32SourceNum - (u16)(f32Multiple * i)), &strExtremum);
}
else
{
this->findExtremum(&pu16Source[(u32)(f32Multiple * i)], (u16)f32Multiple, &strExtremum);
}
// 获得最大值、最小值的位置
u32MaxPos = (u32)(f32Multiple * i) + strExtremum.u32MaxPos;
u32MinPos = (u32)(f32Multiple * i) + strExtremum.u32MinPos;
if (u32MinPos < u32MaxPos)
{
pf32TempDot[k] = pu16Source[u32MinPos];
pf32TempDot[k+1] = pu16Source[u32MaxPos];
}
else
{
pf32TempDot[k] = pu16Source[u32MaxPos];
pf32TempDot[k+1] = pu16Source[u32MinPos];
}
k += 2;
}
// 假如有4个数据在pf32TempDot中,pf32TempDot[0] < pf32TempDot[1], pf32TempDot[2] < pf32TempDot[3]
// 在这4个数据中需要选择2点作为最终输出波形数据,重点是比较pf32TempDot[1]和pf32TempDot[2]是否是极值
// 若无极值 pf32TempDot[0] < pf32TempDot[1] < pf32TempDot[2] < pf32TempDot[3],则取pf32Des[j] = (pf32TempDot[1] + pf32TempDot[2]) / 2
// 若都是极值 pf32TempDot[2] < pf32TempDot[3] < pf32TempDot[0] < pf32TempDot[1],则取pf32Des[j] = pf32TempDot[1],pf32TempDot[i+2] = u16Dot[2]
// 若只有一个极值 pf32TempDot[0] < pf32TempDot[2] < pf32TempDot[3] < pf32TempDot[1],则取pf32Des[j] = pf32TempDot[1]
pu16Des[0] = pf32TempDot[0];
for (u32 i = 1, j = 0; i <= k; i +=2, j++)
{
u16Dot[0] = pu16Des[j];
u16Dot[1] = pf32TempDot[i];
u16Dot[2] = pf32TempDot[i+1];
u16Dot[3] = pf32TempDot[i+2];
// 查找最大值、最小值
this->findExtremum(u16Dot, 4, &strExtremum);
u32MaxPos = strExtremum.u32MaxPos;
u32MinPos = strExtremum.u32MinPos;
if ((u32MinPos != 1) && (u32MaxPos != 2) && (u32MinPos != 2) && (u32MaxPos != 1))
{
pu16Des[j] = (u16Dot[1] + u16Dot[2]) / 2;
}
else if (((u32MinPos == 2) && (u32MaxPos == 1)) || ((u32MinPos == 1) && (u32MaxPos == 2)))
{
pu16Des[j] = u16Dot[1];
pf32TempDot[i+2] = u16Dot[2];
}
else if ((u32MaxPos == 1) || (u32MinPos == 1))
{
pu16Des[j] = u16Dot[1];
}
else if ((u32MinPos == 2) || (u32MaxPos == 2))
{
pu16Des[j] = u16Dot[2];
}
pu16Des[j+1] = pf32TempDot[i];
}
free(pf32TempDot);
pf32TempDot = NULL;
}
/**
* @brief 查找极值点
* @param 原数据
* @param 数据长度
* @param 极值结构
*/
void AwgGuiWaveformWidget::findExtremum(u16 *pu16Value, u32 u32Length, ExtremumValueStru *pstExtremumValue)
{
u32 u32MinPos = 0, u32MaxPos = 0;
u16 u16Min = 0, u16Max = 0;
if (pu16Value != NULL)
{
u16Min = pu16Value[0];
u16Max = pu16Value[0];
}
// 查找极小值、极大值
for (u32 i = 0; i < u32Length; i ++)
{
if (pu16Value[i] < u16Min)
{
u32MinPos = i;
u16Min = pu16Value[i];
}
else if (pu16Value[i] > u16Max)
{
u32MaxPos = i;
u16Max = pu16Value[i];
}
}
pstExtremumValue->u32MinPos = u32MinPos;
pstExtremumValue->u16Min = u16Min;
pstExtremumValue->u32MaxPos = u32MaxPos;
pstExtremumValue->u16Max = u16Max;
}