实验性功能:移除「差异放大」、新增「弱波增强」;修复放大后拖拽光标越出视界
- 移除差异放大:ComputeDiffAmplify、EdgePanelKind::DIFF_AMP 面板、DIFF_AMP_*
编辑目标、菜单项与相关缓存,并删除仅供它使用的 SlidingMax / SlidingExtrema /
float 版滑动平均。
- 新增弱波增强 ComputeWeakWaveBoost(values, level, out)(O(n)):
1) 对轻度平滑(5 点滑动平均)后的信号扫描单调段,方向翻转处即为波峰/波谷;
2) 波峰低于左右两个波峰均值(波谷高于左右两个波谷均值)即判为弱波;
3) 波峰目标 = 较小波峰 + 等级×(较大−较小);
波谷目标 = 较大波谷 − 等级×(较大−较小);
4) 极值点取目标值,两侧数据点在相邻极值点的偏移量之间用平滑步进过渡,
因此健康周期逐位不变、数据端点原样保留。
- 弱波增强面板:逐信号复选框 + 「弱波增强等级」滑块(0–100%,整个网格共用)
+ 「构建为新信号」按钮;构建名形如「<原信号> (弱波增强 M%)」。
等级进 SceneContentHash,改动即触发重绘;Lane 新增
weakBoost/weakBoostLevel/weakBoostItems,并在 LaneCarry、SplitLane、
RemapAfterSignalInsert/Removal 中同步。
- 修复:放大到一定程度后左右拖拽时间光标(尤其抓取较宽的读数标签、抓取偏移较大时)
会把光标时间推到视界之外;现在 CURSOR_MOVE 与 CURSOR_SPAN_MOVE 结束后
按可见区间夹取(视图变化仍不移动光标,保留贴边读数与方向三角)。
- 离屏验证(窗口隐藏,不占用鼠标/键盘/屏幕):295 项检查全部通过,
含等级 0/50/100% 的目标值与健康区逐位不变、滑块拖拽与左右钳制、
合成纹波端到端恢复(弱周期峰峰值 100→160,健康周期 200 不变)、
光标拖拽始终落在可见区间内。
This commit is contained in:
1 parent
d4206a8d67
commit
67f659ad23
6 files changed
+811
-764
No files matched your search
@@ -239,28 +239,36 @@ namespace jdi
|
||||
bool ApplyPendingRename();
|
||||
|
||||
/**
|
||||
* @brief 应用绘图区提交的「均值滤波 → 构建为新信号」请求。
|
||||
* @brief 应用绘图区提交的「实验性功能 → 构建为新信号」请求。
|
||||
*
|
||||
* 为指定网格内的每条可见信号各构建一条 N 点均值滤波信号,命名为
|
||||
* `<原信号名称> (N点均值)`,插入到原信号所在组的原信号位置**下方**,
|
||||
* 并把新信号所在的网格移动到原信号网格的下方。
|
||||
* 为指定网格内的每条被勾选信号各构建一条派生信号(多阶均值滤波或弱波增强),
|
||||
* 命名为 `<原信号名称> (N点均值…)` / `<原信号名称> (弱波增强 M%)`,
|
||||
* 插入到原信号所在组的原信号位置**下方**,并把新信号所在的网格移动到原信号网格的下方。
|
||||
*
|
||||
* @return 实际构建了新信号返回 true。
|
||||
*/
|
||||
bool ApplyPendingDerivedBuild();
|
||||
|
||||
/**
|
||||
* @brief 把一条多阶均值滤波派生信号插入数据层并同步各视图。
|
||||
* @param [IN] fileIndex 原信号所属文件下标。
|
||||
* @param [IN] signalIndex 原信号下标。
|
||||
* @param [IN] points 均值点数 X(滑平半径)。
|
||||
* @param [IN] order 阶数 N(迭代次数)。
|
||||
* @brief 派生信号构建请求(多阶均值滤波 / 弱波增强共用同一套插入流程)。
|
||||
*/
|
||||
struct DerivedSignalRequest
|
||||
{
|
||||
int fileIndex = -1; /**< 原信号所属文件下标。 */
|
||||
int signalIndex = -1; /**< 原信号下标。 */
|
||||
int points = 5; /**< 多阶均值滤波:均值点数 X(滑平半径)。 */
|
||||
int order = 1; /**< 多阶均值滤波:阶数 N(迭代次数)。 */
|
||||
int levelPercent = 50; /**< 弱波增强:增强等级(0–100)。 */
|
||||
bool weakBoost = false; /**< true = 弱波增强,false = 多阶均值滤波。 */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 把一条派生信号(多阶均值滤波 / 弱波增强)插入数据层并同步各视图。
|
||||
* @param [IN] request 构建请求。
|
||||
* @param [IN] makeVisible 是否在当前标签页中勾选新信号。
|
||||
* @return 构建并插入成功返回 true。
|
||||
*/
|
||||
bool BuildDerivedSignal(int fileIndex, int signalIndex, int points, int order,
|
||||
bool diffAmp,
|
||||
bool makeVisible);
|
||||
bool BuildDerivedSignal(const DerivedSignalRequest& request, bool makeVisible);
|
||||
|
||||
/**
|
||||
* @brief 弹出文件选择对话框并加载所选文件。
|
||||
|
||||
@@ -1461,71 +1461,67 @@ namespace jdi
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Application::BuildDerivedSignal(int fileIndex, int signalIndex, int points, int order,
|
||||
bool diffAmp, bool makeVisible)
|
||||
bool Application::BuildDerivedSignal(const DerivedSignalRequest& request, bool makeVisible)
|
||||
{
|
||||
const DataFile* file = m_dataSet.FileAt(fileIndex);
|
||||
if (file == nullptr || signalIndex < 0 || signalIndex >= static_cast<int>(file->signals.size()))
|
||||
const DataFile* file = m_dataSet.FileAt(request.fileIndex);
|
||||
if (file == nullptr || request.signalIndex < 0 ||
|
||||
request.signalIndex >= static_cast<int>(file->signals.size()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const SignalData& source = file->signals[static_cast<std::size_t>(signalIndex)];
|
||||
const SignalData& source = file->signals[static_cast<std::size_t>(request.signalIndex)];
|
||||
const std::wstring baseName = source.Title();
|
||||
|
||||
// 1. 计算派生采样值(与网格内的预览曲线共用同一实现,因此逐位一致)。
|
||||
// 多阶均值滤波形如「<原信号名称> (N点均值×M阶)」,
|
||||
// 弱波增强形如「<原信号名称> (弱波增强 M%)」。
|
||||
std::vector<float> derived_values;
|
||||
if (diffAmp)
|
||||
{
|
||||
ComputeDiffAmplify(source.values, points, order, derived_values);
|
||||
}
|
||||
else
|
||||
{
|
||||
ComputeMovingAverageIterated(source.values, points, order, derived_values);
|
||||
}
|
||||
|
||||
// 2. 组装新信号:均值滤波形如「<原信号名称> (N点均值×M阶)」,
|
||||
// 差异放大形如「<原信号名称> (X点差异放大×N倍)」。
|
||||
SignalData derived;
|
||||
if (diffAmp)
|
||||
if (request.weakBoost)
|
||||
{
|
||||
derived.name = baseName + L" (" + std::to_wstring(points) + L"点差异放大×" +
|
||||
std::to_wstring(order) + L"倍)";
|
||||
ComputeWeakWaveBoost(source.values, static_cast<double>(request.levelPercent) / 100.0,
|
||||
derived_values);
|
||||
derived.name = baseName + L" (弱波增强 " + std::to_wstring(request.levelPercent) + L"%)";
|
||||
}
|
||||
else
|
||||
{
|
||||
derived.name = baseName + L" (" + std::to_wstring(points) + L"点均值";
|
||||
if (order > 1)
|
||||
ComputeMovingAverageIterated(source.values, request.points, request.order, derived_values);
|
||||
derived.name = baseName + L" (" + std::to_wstring(request.points) + L"点均值";
|
||||
if (request.order > 1)
|
||||
{
|
||||
derived.name += L"×" + std::to_wstring(order) + L"阶";
|
||||
derived.name += L"×" + std::to_wstring(request.order) + L"阶";
|
||||
}
|
||||
derived.name += L")";
|
||||
}
|
||||
|
||||
// 2. 组装新信号。
|
||||
derived.rawHeader = derived.name;
|
||||
derived.unit = source.unit;
|
||||
derived.values.assign(derived_values.begin(), derived_values.end());
|
||||
|
||||
// 3. 插入到原信号的下方(数据层 + 各标签页引用重映射)。
|
||||
int newIndex = -1;
|
||||
if (!m_dataSet.InsertDerivedSignal(fileIndex, signalIndex, std::move(derived), newIndex))
|
||||
if (!m_dataSet.InsertDerivedSignal(request.fileIndex, request.signalIndex, std::move(derived),
|
||||
newIndex))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (TabConfig& tab : m_tabs)
|
||||
{
|
||||
tab.RemapAfterSignalInsert(fileIndex, newIndex);
|
||||
tab.RemapAfterSignalInsert(request.fileIndex, newIndex);
|
||||
}
|
||||
|
||||
// 4. 在当前标签页中勾选新信号,并把它所在的网格移到原信号网格的下方。
|
||||
if (makeVisible && !m_tabs.empty())
|
||||
{
|
||||
SignalRef derivedRef;
|
||||
derivedRef.fileIndex = fileIndex;
|
||||
derivedRef.fileIndex = request.fileIndex;
|
||||
derivedRef.signalIndex = newIndex;
|
||||
ActiveTab().SetVisible(derivedRef, true);
|
||||
|
||||
SignalRef sourceRef;
|
||||
sourceRef.fileIndex = fileIndex;
|
||||
sourceRef.signalIndex = signalIndex;
|
||||
sourceRef.fileIndex = request.fileIndex;
|
||||
sourceRef.signalIndex = request.signalIndex;
|
||||
ActiveTab().MoveLaneOfSignalBelow(derivedRef, sourceRef);
|
||||
}
|
||||
|
||||
@@ -1536,18 +1532,9 @@ namespace jdi
|
||||
|
||||
bool Application::ApplyPendingDerivedBuild()
|
||||
{
|
||||
// 两类「构建为新信号」请求(均值滤波 / 差异放大)机制完全一致,
|
||||
// 两类「构建为新信号」请求(均值滤波 / 弱波增强)机制完全一致,
|
||||
// 统一整理成同一份构建清单后按下标降序处理。
|
||||
struct BuildRequest
|
||||
{
|
||||
int fileIndex = -1;
|
||||
int signalIndex = -1;
|
||||
int first = 0;
|
||||
int second = 0;
|
||||
bool diffAmp = false;
|
||||
};
|
||||
|
||||
std::vector<BuildRequest> requests;
|
||||
std::vector<DerivedSignalRequest> requests;
|
||||
{
|
||||
int laneIndex = -1;
|
||||
std::vector<PlotView::MeanFilterBuild> items;
|
||||
@@ -1555,29 +1542,28 @@ namespace jdi
|
||||
{
|
||||
for (const PlotView::MeanFilterBuild& item : items)
|
||||
{
|
||||
BuildRequest request;
|
||||
DerivedSignalRequest request;
|
||||
request.fileIndex = item.fileIndex;
|
||||
request.signalIndex = item.signalIndex;
|
||||
request.first = item.points;
|
||||
request.second = item.order;
|
||||
request.diffAmp = false;
|
||||
request.points = item.points;
|
||||
request.order = item.order;
|
||||
request.weakBoost = false;
|
||||
requests.push_back(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
int laneIndex = -1;
|
||||
std::vector<PlotView::DiffAmpBuild> items;
|
||||
if (m_plot.TakePendingDiffAmpBuild(laneIndex, items))
|
||||
std::vector<PlotView::WeakBoostBuild> items;
|
||||
if (m_plot.TakePendingWeakBoostBuild(laneIndex, items))
|
||||
{
|
||||
for (const PlotView::DiffAmpBuild& item : items)
|
||||
for (const PlotView::WeakBoostBuild& item : items)
|
||||
{
|
||||
BuildRequest request;
|
||||
DerivedSignalRequest request;
|
||||
request.fileIndex = item.fileIndex;
|
||||
request.signalIndex = item.signalIndex;
|
||||
request.first = item.points;
|
||||
request.second = item.gain;
|
||||
request.diffAmp = true;
|
||||
request.levelPercent = item.levelPercent;
|
||||
request.weakBoost = true;
|
||||
requests.push_back(request);
|
||||
}
|
||||
}
|
||||
@@ -1594,7 +1580,7 @@ namespace jdi
|
||||
// **同一文件内必须按下标降序处理**:每次插入只让插入点之后的信号下标 +1,
|
||||
// 降序处理可保证尚未处理的信号下标始终有效(升序会把新插入的信号当成原信号)。
|
||||
std::sort(requests.begin(), requests.end(),
|
||||
[](const BuildRequest& a, const BuildRequest& b)
|
||||
[](const DerivedSignalRequest& a, const DerivedSignalRequest& b)
|
||||
{
|
||||
if (a.fileIndex != b.fileIndex)
|
||||
{
|
||||
@@ -1604,35 +1590,29 @@ namespace jdi
|
||||
});
|
||||
|
||||
int built = 0;
|
||||
int lastFirst = 0;
|
||||
int lastSecond = 1;
|
||||
bool lastDiffAmp = false;
|
||||
for (const BuildRequest& request : requests)
|
||||
DerivedSignalRequest last;
|
||||
for (const DerivedSignalRequest& request : requests)
|
||||
{
|
||||
if (BuildDerivedSignal(request.fileIndex, request.signalIndex, request.first,
|
||||
request.second, request.diffAmp, true))
|
||||
if (BuildDerivedSignal(request, true))
|
||||
{
|
||||
++built;
|
||||
lastFirst = request.first;
|
||||
lastSecond = request.second;
|
||||
lastDiffAmp = request.diffAmp;
|
||||
last = request;
|
||||
}
|
||||
}
|
||||
|
||||
if (built > 0)
|
||||
{
|
||||
std::wstring text = L"已构建 " + std::to_wstring(built) + L" 条 ";
|
||||
if (lastDiffAmp)
|
||||
if (last.weakBoost)
|
||||
{
|
||||
text += std::to_wstring(lastFirst) + L"点差异放大×" +
|
||||
std::to_wstring(lastSecond) + L"倍信号。";
|
||||
text += L"弱波增强 " + std::to_wstring(last.levelPercent) + L"% 信号。";
|
||||
}
|
||||
else
|
||||
{
|
||||
text += std::to_wstring(lastFirst) + L"点均值";
|
||||
if (lastSecond > 1)
|
||||
text += std::to_wstring(last.points) + L"点均值";
|
||||
if (last.order > 1)
|
||||
{
|
||||
text += L"×" + std::to_wstring(lastSecond) + L"阶";
|
||||
text += L"×" + std::to_wstring(last.order) + L"阶";
|
||||
}
|
||||
text += L"滤波信号。";
|
||||
}
|
||||
@@ -1769,11 +1749,11 @@ namespace jdi
|
||||
meanFilter.checked = m_plot.LaneMeanFilter(laneIndex);
|
||||
experimental.submenu.push_back(meanFilter);
|
||||
|
||||
MenuItem diffAmp;
|
||||
diffAmp.label = L"差异放大";
|
||||
diffAmp.id = PLOT_CMD_LANE_DIFF_AMP;
|
||||
diffAmp.checked = m_plot.LaneDiffAmp(laneIndex);
|
||||
experimental.submenu.push_back(diffAmp);
|
||||
MenuItem weakBoost;
|
||||
weakBoost.label = L"弱波增强";
|
||||
weakBoost.id = PLOT_CMD_LANE_WEAK_BOOST;
|
||||
weakBoost.checked = m_plot.LaneWeakBoost(laneIndex);
|
||||
experimental.submenu.push_back(weakBoost);
|
||||
}
|
||||
items.push_back(experimental);
|
||||
|
||||
@@ -1888,9 +1868,9 @@ namespace jdi
|
||||
// 「实验性功能 → 均值滤波」:切换均值滤波曲线与参数面板。
|
||||
m_plot.ToggleLaneMeanFilter(laneIndex);
|
||||
break;
|
||||
case PLOT_CMD_LANE_DIFF_AMP:
|
||||
// 「实验性功能 → 差异放大」:切换差异放大曲线与参数面板。
|
||||
m_plot.ToggleLaneDiffAmp(laneIndex);
|
||||
case PLOT_CMD_LANE_WEAK_BOOST:
|
||||
// 「实验性功能 → 弱波增强」:切换弱波增强曲线与参数面板。
|
||||
m_plot.ToggleLaneWeakBoost(laneIndex);
|
||||
break;
|
||||
case PLOT_CMD_LANE_SPLIT:
|
||||
// 「拆分当前网格」:信号按个拆成独立网格,新网格顺次插入其下方。
|
||||
@@ -2390,7 +2370,7 @@ namespace jdi
|
||||
{
|
||||
// 绘图区内的点击也可能提交图例改名,需要立刻落到数据层。
|
||||
ApplyPendingRename();
|
||||
// 「均值滤波 → 构建为新信号」按钮:立即构建新信号并同步各视图。
|
||||
// 「构建为新信号」按钮(均值滤波 / 弱波增强):立即构建新信号并同步各视图。
|
||||
ApplyPendingDerivedBuild();
|
||||
InvalidateRect(hwnd, nullptr, FALSE);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace jdi
|
||||
MOVE_SIGNAL, /**< 拖拽信号曲线到其它网格。 */
|
||||
EDGE_MOVE, /**< 拖动「边沿计数」的横向光标(上下移动幅值)。 */
|
||||
EDGE_PANEL_MOVE, /**< 拖动边沿计数浮动面板。 */
|
||||
BOOST_LEVEL, /**< 拖动「弱波增强」面板中的等级滑块。 */
|
||||
LANE_REORDER /**< 拖动网格图例中的 GX 编号徽标:上下调整网格次序。 */
|
||||
};
|
||||
|
||||
@@ -57,9 +58,7 @@ namespace jdi
|
||||
EDGE_CENTER_POINTS, /**< 编辑「中心轴边沿计数」的均值点数 X。 */
|
||||
EDGE_CENTER_ORDER, /**< 编辑「中心轴边沿计数」的阶数 N。 */
|
||||
MEAN_FILTER_POINTS, /**< 编辑「均值滤波」的均值点数 X。 */
|
||||
MEAN_FILTER_ORDER, /**< 编辑「均值滤波」的阶数 N。 */
|
||||
DIFF_AMP_POINTS, /**< 编辑「差异放大」的窗口点数 X。 */
|
||||
DIFF_AMP_ORDER /**< 编辑「差异放大」的放大倍数 N。 */
|
||||
MEAN_FILTER_ORDER /**< 编辑「均值滤波」的阶数 N。 */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -77,7 +76,7 @@ namespace jdi
|
||||
PLOT_CMD_LANE_EDGE_CENTER = 8, /**< 切换本网格的「实验性功能 → 边沿计数(中心轴)」开关。 */
|
||||
PLOT_CMD_LANE_SPLIT = 9, /**< 拆分当前网格:把网格内信号按个拆成独立网格并顺次下移编号。 */
|
||||
PLOT_CMD_LANE_MEAN_FILTER = 10, /**< 切换本网格的「实验性功能 → 均值滤波」开关。 */
|
||||
PLOT_CMD_LANE_DIFF_AMP = 11 /**< 切换本网格的「实验性功能 → 差异放大」开关。 */
|
||||
PLOT_CMD_LANE_WEAK_BOOST = 11 /**< 切换本网格的「实验性功能 → 弱波增强」开关。 */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -88,7 +87,7 @@ namespace jdi
|
||||
COUNT = 0, /**< 边沿计数。 */
|
||||
CENTER = 1, /**< 边沿计数(中心轴)。 */
|
||||
MEAN = 2, /**< 均值滤波。 */
|
||||
DIFF_AMP = 3 /**< 差异放大。 */
|
||||
BOOST = 3 /**< 弱波增强。 */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -523,84 +522,96 @@ namespace jdi
|
||||
bool TakePendingMeanFilterBuild(int& laneIndex, std::vector<MeanFilterBuild>& items);
|
||||
|
||||
/**
|
||||
* @brief 「实验性功能 → 差异放大」的「构建为新信号」单个请求
|
||||
* (一个被勾选的信号 + 自己的参数)。
|
||||
* @brief 「实验性功能 → 弱波增强」的「构建为新信号」单个请求
|
||||
* (一个被勾选的信号 + 整个网格共用的增强等级)。
|
||||
*/
|
||||
struct DiffAmpBuild
|
||||
struct WeakBoostBuild
|
||||
{
|
||||
int fileIndex = -1; /**< 信号所属文件下标。 */
|
||||
int signalIndex = -1; /**< 文件内信号下标。 */
|
||||
int points = 80; /**< 窗口点数 X(略大于纹波周期的一半)。 */
|
||||
int gain = 2; /**< 放大倍数 N。 */
|
||||
int levelPercent = 50; /**< 弱波增强等级(0–100)。 */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 取出「差异放大 → 构建为新信号」请求(由面板底部按钮触发)。
|
||||
* @brief 取出「弱波增强 → 构建为新信号」请求(由面板底部按钮触发)。
|
||||
* @param [OUT] laneIndex 触发该请求的网格下标。
|
||||
* @param [OUT] items 需要构建的信号及其参数(按信号在网格内的顺序)。
|
||||
* @return 存在待处理请求返回 true(取出后清空)。
|
||||
*/
|
||||
bool TakePendingDiffAmpBuild(int& laneIndex, std::vector<DiffAmpBuild>& items);
|
||||
bool TakePendingWeakBoostBuild(int& laneIndex, std::vector<WeakBoostBuild>& items);
|
||||
|
||||
/**
|
||||
* @brief 切换某网格的「差异放大」开关。
|
||||
* @brief 切换某网格的「弱波增强」开关。
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
* @param [IN] enabled 是否开启。
|
||||
* @return 状态发生变化返回 true。
|
||||
*/
|
||||
bool SetLaneDiffAmp(int laneIndex, bool enabled);
|
||||
bool SetLaneWeakBoost(int laneIndex, bool enabled);
|
||||
|
||||
/**
|
||||
* @brief 查询某网格的「差异放大」开关。
|
||||
* @brief 查询某网格的「弱波增强」开关。
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
* @return 已开启返回 true。
|
||||
*/
|
||||
bool LaneDiffAmp(int laneIndex) const;
|
||||
bool LaneWeakBoost(int laneIndex) const;
|
||||
|
||||
/**
|
||||
* @brief 切换某网格的「差异放大」开关。
|
||||
* @brief 切换某网格的「弱波增强」开关。
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
* @return 切换后的状态。
|
||||
*/
|
||||
bool ToggleLaneDiffAmp(int laneIndex);
|
||||
bool ToggleLaneWeakBoost(int laneIndex);
|
||||
|
||||
/**
|
||||
* @brief 获取差异放大曲线(按「信号 + 窗口点数 + 放大倍数」缓存)。
|
||||
* @brief 读取某网格的弱波增强等级(0–1)。
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
* @return 增强等级;网格不存在时返回 0.5。
|
||||
*/
|
||||
double LaneWeakBoostLevel(int laneIndex) const;
|
||||
|
||||
/**
|
||||
* @brief 设置某网格的弱波增强等级(0–1,超出范围会被夹取)。
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
* @param [IN] level 增强等级。
|
||||
* @return 等级发生变化返回 true。
|
||||
*/
|
||||
bool SetLaneWeakBoostLevel(int laneIndex, double level);
|
||||
|
||||
/**
|
||||
* @brief 获取弱波增强曲线(按「信号 + 增强等级」缓存)。
|
||||
* @param [IN] signal 目标信号。
|
||||
* @param [IN] points 窗口点数 X。
|
||||
* @param [IN] gain 放大倍数 N。
|
||||
* @param [IN] levelPercent 弱波增强等级(0–100,整数百分比)。
|
||||
* @return 曲线数值数组(长度与 `signal.values` 相同;缺失处为 NaN)。
|
||||
*/
|
||||
const std::vector<float>& DiffAmpCurveFor(const SignalData& signal, int points, int gain) const;
|
||||
const std::vector<float>& WeakBoostCurveFor(const SignalData& signal, int levelPercent) const;
|
||||
|
||||
/**
|
||||
* @brief 取某个时刻的差异放大曲线取值(用于纵向光标的取值标注)。
|
||||
* @brief 取某个时刻的弱波增强曲线取值(用于纵向光标的取值标注)。
|
||||
* @param [IN] file 信号所属文件。
|
||||
* @param [IN] signal 目标信号。
|
||||
* @param [IN] points 窗口点数 X(略大于纹波周期的一半)。
|
||||
* @param [IN] gain 放大倍数 N。
|
||||
* @param [IN] levelPercent 弱波增强等级(0–100)。
|
||||
* @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;
|
||||
bool WeakBoostValueAt(const DataFile& file, const SignalData& signal, int levelPercent,
|
||||
double time, double& value) const;
|
||||
|
||||
/**
|
||||
* @brief 切换某个信号在「差异放大」面板中的预览勾选状态。
|
||||
* @brief 切换某个信号在「弱波增强」面板中的预览勾选状态。
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
* @param [IN] ref 目标信号。
|
||||
* @return 切换后的勾选状态。
|
||||
*/
|
||||
bool ToggleLaneDiffAmpSignal(int laneIndex, const SignalRef& ref);
|
||||
bool ToggleLaneWeakBoostSignal(int laneIndex, const SignalRef& ref);
|
||||
|
||||
/**
|
||||
* @brief 查询某个信号在「差异放大」面板中的预览勾选状态。
|
||||
* @brief 查询某个信号在「弱波增强」面板中的预览勾选状态。
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
* @param [IN] ref 目标信号。
|
||||
* @return 已勾选返回 true。
|
||||
*/
|
||||
bool LaneDiffAmpSignalEnabled(int laneIndex, const SignalRef& ref) const;
|
||||
bool LaneWeakBoostSignalEnabled(int laneIndex, const SignalRef& ref) const;
|
||||
|
||||
/**
|
||||
* @brief 直接把文本解析为网格 Y 轴上限/下限并应用(供菜单内联输入框提交使用)。
|
||||
@@ -1052,6 +1063,7 @@ namespace jdi
|
||||
gd::RectF close; /**< ✕ 关闭按钮。 */
|
||||
gd::RectF edit; /**< 面板底部编辑行(无编辑内容时宽度为 0)。 */
|
||||
gd::RectF button; /**< 面板底部按钮(无按钮时宽度为 0)。 */
|
||||
gd::RectF slider; /**< 「弱波增强」等级滑块的轨道矩形(无滑块时宽度为 0)。 */
|
||||
int rows = 0; /**< 统计行数(每条可见信号一行)。 */
|
||||
/**
|
||||
* @brief 「逐条目」面板的矩形(MEAN 与 CENTER 面板共用同一套排布)。
|
||||
@@ -1176,15 +1188,14 @@ namespace jdi
|
||||
int points, int order) const;
|
||||
|
||||
/**
|
||||
* @brief 绘制某条信号的差异放大曲线(与均值滤波曲线同一配色派生规则)。
|
||||
* @brief 绘制某条信号的弱波增强曲线(与均值滤波曲线同一配色派生规则)。
|
||||
* @param [IN,OUT] g 绘图上下文。
|
||||
* @param [IN] resolved 信号视图。
|
||||
* @param [IN] lane 网格绘制信息。
|
||||
* @param [IN] points 窗口点数 X(局部差异强度统计半径)。
|
||||
* @param [IN] gain 放大倍数 N(最大增益)。
|
||||
* @param [IN] levelPercent 弱波增强等级(0–100)。
|
||||
*/
|
||||
void PaintDiffAmpCurve(gd::Graphics& g, const ResolvedSignal& resolved, const LaneVisual& lane,
|
||||
int points, int gain) const;
|
||||
void PaintWeakBoostCurve(gd::Graphics& g, const ResolvedSignal& resolved, const LaneVisual& lane,
|
||||
int levelPercent) const;
|
||||
|
||||
/**
|
||||
* @brief 数据点标记的位置与"越界方向"(用于决定画圆点还是贴边三角)。
|
||||
@@ -1400,9 +1411,10 @@ namespace jdi
|
||||
bool m_pendingRename = false; /**< 是否存在待应用的重命名请求。 */
|
||||
|
||||
int m_pendingMeanFilterLane = -1; /**< 待构建的均值滤波信号所属网格下标(-1 表示无请求)。 */
|
||||
int m_pendingDiffAmpLane = -1; /**< 待构建的差异放大信号所属网格下标(-1 表示无请求)。 */
|
||||
int m_pendingWeakBoostLane = -1; /**< 待构建的弱波增强信号所属网格下标(-1 表示无请求)。 */
|
||||
std::vector<MeanFilterBuild> m_pendingMeanFilterItems; /**< 待构建的信号及其参数。 */
|
||||
std::vector<DiffAmpBuild> m_pendingDiffAmpItems; /**< 待构建的差异放大信号及其参数。 */
|
||||
std::vector<WeakBoostBuild> m_pendingWeakBoostItems; /**< 待构建的弱波增强信号及其参数。 */
|
||||
int m_boostDragLane = -1; /**< 正在拖动等级滑块的面板所属网格。 */
|
||||
|
||||
/**
|
||||
* @brief 实验性功能浮动面板的 ✕ 处于"已按下、等待抬起确认"状态。
|
||||
@@ -1458,15 +1470,14 @@ namespace jdi
|
||||
};
|
||||
mutable std::deque<MeanCurveEntry> m_meanCurveCache;
|
||||
|
||||
/** 多阶均值滤波曲线缓存项(按「信号指针 + 均值点数 + 阶数」标识)。 */
|
||||
struct DiffAmpCurveEntry
|
||||
/** 弱波增强曲线缓存项(按「信号指针 + 增强等级百分比」标识)。 */
|
||||
struct WeakBoostCurveEntry
|
||||
{
|
||||
const SignalData* signal = nullptr;
|
||||
int points = 80; /**< 窗口点数 X。 */
|
||||
int gain = 2; /**< 放大倍数 N。 */
|
||||
int levelPercent = 50; /**< 弱波增强等级(0–100)。 */
|
||||
std::vector<float> values; /**< 与 signal->values 等长;缺失处为 NaN。 */
|
||||
};
|
||||
mutable std::deque<DiffAmpCurveEntry> m_diffAmpCurveCache;
|
||||
mutable std::deque<WeakBoostCurveEntry> m_weakBoostCurveCache;
|
||||
|
||||
/** 中心轴边沿统计缓存项(增量统计机制与 `EdgeCountEntry` 完全一致)。 */
|
||||
struct EdgeCenterCountEntry
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user