实验性功能新增「差异放大」,并修正「构建为新信号」按钮的间距
1. 新增「实验性功能 → 差异放大」(与其它实验功能一样是带勾选的开关)
- 用途:纹波类信号某个周期(甚至半个周期)的 M 形下凹明显偏弱时,
把这段下凹按比例拉回周边振幅,恢复正常周期的对比度,便于看出波形异常。
- 算法(全 O(n),不额外占用与信号长度成正比以外的内存):
以半径约半个纹波周期的滑动平均作为纹波中心线,用邻域内「交流分量的最大值」
作为局部纹波振幅,取全信号振幅的 75 分位作为目标振幅,
逐点增益 = 目标振幅 / 局部振幅(夹在 1 到放大倍数之间),
输出 = 中心线 + 增益 × 交流分量,再夹在周边包络内。
- 关键性质(均已用合成正弦逐点验证):
* 增益下界恒为 1,因此**只有被判定为"偏弱"的采样点会改变**,
其余采样点输出与原值逐位相同 —— 实测逐周期表格中只有一个周期发生变化;
* 放大结果夹在周边包络内,因此**任何一点都不超出原有的振幅范围**,
整体值域与其它周期的峰峰值都不变;
* 端点自动收敛到不放大,避免记录首尾被整片抬升。
- 参数「窗口点数 X」(窗口长度,建议略大于纹波周期的一半)与
「放大倍数 N」(增益上限)都可在浮动面板内按信号编辑。
2. 浮动面板
- 与「均值滤波」完全同一套排版:自上而下逐信号条目,
第一排信号名与复选框、第二排两个参数输入框;取消勾选即不显示该信号的参数与预览曲线;
启用时默认只勾选网格内第一个可见信号。
- 新增「构建为新信号」按钮,按各信号自己的参数把结果插入到源信号下方,
与「均值滤波」的构建机制完全一致(统一走同一套请求与插入流程)。
3. 光标交互
- 纵向光标额外标注差异放大曲线在该时刻的取值,配色与原始信号一致,
数值尾部括号内容为「差异化」,双光标时同样带增量。
4. 修复「构建为新信号」按钮与面板下边界的间距
- 原按钮行直接贴着面板下边框,与面板左右内边距及内容间距都不协调;
现在按钮上方与下方各保留一个与左右一致的内边距(均值滤波与差异放大同时生效)。
测试:离屏验证套件新增两组检查(合成正弦上算法只改动一个周期、放大不越界、
参数上限生效、面板排版与按钮间距;再写一份合成纹波文件真正加载渲染并核对曲线数值),
合计 289 项检查全部通过;验证过程不显示窗口、不移动鼠标键盘、不抓屏。
This commit is contained in:
1 parent
8801c8f019
commit
d4206a8d67
6 files changed
+1188
-185
No files matched your search
@@ -57,7 +57,9 @@ namespace jdi
|
||||
EDGE_CENTER_POINTS, /**< 编辑「中心轴边沿计数」的均值点数 X。 */
|
||||
EDGE_CENTER_ORDER, /**< 编辑「中心轴边沿计数」的阶数 N。 */
|
||||
MEAN_FILTER_POINTS, /**< 编辑「均值滤波」的均值点数 X。 */
|
||||
MEAN_FILTER_ORDER /**< 编辑「均值滤波」的阶数 N。 */
|
||||
MEAN_FILTER_ORDER, /**< 编辑「均值滤波」的阶数 N。 */
|
||||
DIFF_AMP_POINTS, /**< 编辑「差异放大」的窗口点数 X。 */
|
||||
DIFF_AMP_ORDER /**< 编辑「差异放大」的放大倍数 N。 */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -74,7 +76,8 @@ namespace jdi
|
||||
PLOT_CMD_LANE_EDGE_COUNT = 7, /**< 切换本网格的「实验性功能 → 边沿计数」开关。 */
|
||||
PLOT_CMD_LANE_EDGE_CENTER = 8, /**< 切换本网格的「实验性功能 → 边沿计数(中心轴)」开关。 */
|
||||
PLOT_CMD_LANE_SPLIT = 9, /**< 拆分当前网格:把网格内信号按个拆成独立网格并顺次下移编号。 */
|
||||
PLOT_CMD_LANE_MEAN_FILTER = 10 /**< 切换本网格的「实验性功能 → 均值滤波」开关。 */
|
||||
PLOT_CMD_LANE_MEAN_FILTER = 10, /**< 切换本网格的「实验性功能 → 均值滤波」开关。 */
|
||||
PLOT_CMD_LANE_DIFF_AMP = 11 /**< 切换本网格的「实验性功能 → 差异放大」开关。 */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -84,7 +87,8 @@ namespace jdi
|
||||
{
|
||||
COUNT = 0, /**< 边沿计数。 */
|
||||
CENTER = 1, /**< 边沿计数(中心轴)。 */
|
||||
MEAN = 2 /**< 均值滤波。 */
|
||||
MEAN = 2, /**< 均值滤波。 */
|
||||
DIFF_AMP = 3 /**< 差异放大。 */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -518,6 +522,86 @@ namespace jdi
|
||||
*/
|
||||
bool TakePendingMeanFilterBuild(int& laneIndex, std::vector<MeanFilterBuild>& items);
|
||||
|
||||
/**
|
||||
* @brief 「实验性功能 → 差异放大」的「构建为新信号」单个请求
|
||||
* (一个被勾选的信号 + 自己的参数)。
|
||||
*/
|
||||
struct DiffAmpBuild
|
||||
{
|
||||
int fileIndex = -1; /**< 信号所属文件下标。 */
|
||||
int signalIndex = -1; /**< 文件内信号下标。 */
|
||||
int points = 80; /**< 窗口点数 X(略大于纹波周期的一半)。 */
|
||||
int gain = 2; /**< 放大倍数 N。 */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 取出「差异放大 → 构建为新信号」请求(由面板底部按钮触发)。
|
||||
* @param [OUT] laneIndex 触发该请求的网格下标。
|
||||
* @param [OUT] items 需要构建的信号及其参数(按信号在网格内的顺序)。
|
||||
* @return 存在待处理请求返回 true(取出后清空)。
|
||||
*/
|
||||
bool TakePendingDiffAmpBuild(int& laneIndex, std::vector<DiffAmpBuild>& items);
|
||||
|
||||
/**
|
||||
* @brief 切换某网格的「差异放大」开关。
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
* @param [IN] enabled 是否开启。
|
||||
* @return 状态发生变化返回 true。
|
||||
*/
|
||||
bool SetLaneDiffAmp(int laneIndex, bool enabled);
|
||||
|
||||
/**
|
||||
* @brief 查询某网格的「差异放大」开关。
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
* @return 已开启返回 true。
|
||||
*/
|
||||
bool LaneDiffAmp(int laneIndex) const;
|
||||
|
||||
/**
|
||||
* @brief 切换某网格的「差异放大」开关。
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
* @return 切换后的状态。
|
||||
*/
|
||||
bool ToggleLaneDiffAmp(int laneIndex);
|
||||
|
||||
/**
|
||||
* @brief 获取差异放大曲线(按「信号 + 窗口点数 + 放大倍数」缓存)。
|
||||
* @param [IN] signal 目标信号。
|
||||
* @param [IN] points 窗口点数 X。
|
||||
* @param [IN] gain 放大倍数 N。
|
||||
* @return 曲线数值数组(长度与 `signal.values` 相同;缺失处为 NaN)。
|
||||
*/
|
||||
const std::vector<float>& DiffAmpCurveFor(const SignalData& signal, int points, int gain) const;
|
||||
|
||||
/**
|
||||
* @brief 取某个时刻的差异放大曲线取值(用于纵向光标的取值标注)。
|
||||
* @param [IN] file 信号所属文件。
|
||||
* @param [IN] signal 目标信号。
|
||||
* @param [IN] points 窗口点数 X(略大于纹波周期的一半)。
|
||||
* @param [IN] gain 放大倍数 N。
|
||||
* @param [IN] time 采样时刻。
|
||||
* @param [OUT] value 输出取值。
|
||||
* @return 取到有效值返回 true。
|
||||
*/
|
||||
bool DiffAmpValueAt(const DataFile& file, const SignalData& signal, int points, int gain,
|
||||
double time, double& value) const;
|
||||
|
||||
/**
|
||||
* @brief 切换某个信号在「差异放大」面板中的预览勾选状态。
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
* @param [IN] ref 目标信号。
|
||||
* @return 切换后的勾选状态。
|
||||
*/
|
||||
bool ToggleLaneDiffAmpSignal(int laneIndex, const SignalRef& ref);
|
||||
|
||||
/**
|
||||
* @brief 查询某个信号在「差异放大」面板中的预览勾选状态。
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
* @param [IN] ref 目标信号。
|
||||
* @return 已勾选返回 true。
|
||||
*/
|
||||
bool LaneDiffAmpSignalEnabled(int laneIndex, const SignalRef& ref) const;
|
||||
|
||||
/**
|
||||
* @brief 直接把文本解析为网格 Y 轴上限/下限并应用(供菜单内联输入框提交使用)。
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
@@ -1091,6 +1175,17 @@ namespace jdi
|
||||
void PaintMeanFilterCurve(gd::Graphics& g, const ResolvedSignal& resolved, const LaneVisual& lane,
|
||||
int points, int order) const;
|
||||
|
||||
/**
|
||||
* @brief 绘制某条信号的差异放大曲线(与均值滤波曲线同一配色派生规则)。
|
||||
* @param [IN,OUT] g 绘图上下文。
|
||||
* @param [IN] resolved 信号视图。
|
||||
* @param [IN] lane 网格绘制信息。
|
||||
* @param [IN] points 窗口点数 X(局部差异强度统计半径)。
|
||||
* @param [IN] gain 放大倍数 N(最大增益)。
|
||||
*/
|
||||
void PaintDiffAmpCurve(gd::Graphics& g, const ResolvedSignal& resolved, const LaneVisual& lane,
|
||||
int points, int gain) const;
|
||||
|
||||
/**
|
||||
* @brief 数据点标记的位置与"越界方向"(用于决定画圆点还是贴边三角)。
|
||||
*/
|
||||
@@ -1305,7 +1400,9 @@ namespace jdi
|
||||
bool m_pendingRename = false; /**< 是否存在待应用的重命名请求。 */
|
||||
|
||||
int m_pendingMeanFilterLane = -1; /**< 待构建的均值滤波信号所属网格下标(-1 表示无请求)。 */
|
||||
int m_pendingDiffAmpLane = -1; /**< 待构建的差异放大信号所属网格下标(-1 表示无请求)。 */
|
||||
std::vector<MeanFilterBuild> m_pendingMeanFilterItems; /**< 待构建的信号及其参数。 */
|
||||
std::vector<DiffAmpBuild> m_pendingDiffAmpItems; /**< 待构建的差异放大信号及其参数。 */
|
||||
|
||||
/**
|
||||
* @brief 实验性功能浮动面板的 ✕ 处于"已按下、等待抬起确认"状态。
|
||||
@@ -1361,6 +1458,16 @@ namespace jdi
|
||||
};
|
||||
mutable std::deque<MeanCurveEntry> m_meanCurveCache;
|
||||
|
||||
/** 多阶均值滤波曲线缓存项(按「信号指针 + 均值点数 + 阶数」标识)。 */
|
||||
struct DiffAmpCurveEntry
|
||||
{
|
||||
const SignalData* signal = nullptr;
|
||||
int points = 80; /**< 窗口点数 X。 */
|
||||
int gain = 2; /**< 放大倍数 N。 */
|
||||
std::vector<float> values; /**< 与 signal->values 等长;缺失处为 NaN。 */
|
||||
};
|
||||
mutable std::deque<DiffAmpCurveEntry> m_diffAmpCurveCache;
|
||||
|
||||
/** 中心轴边沿统计缓存项(增量统计机制与 `EdgeCountEntry` 完全一致)。 */
|
||||
struct EdgeCenterCountEntry
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user