Skip to content

修复轮盘顺时针切换至正上方选区延迟的问题 - #115

Merged
PigeonNian merged 1 commit into
Anvil-Dev:dev/1.21.1from
WhereisFff:fff/1.21.1-fix
Sep 11, 2026
Merged

修复轮盘顺时针切换至正上方选区延迟的问题#115
PigeonNian merged 1 commit into
Anvil-Dev:dev/1.21.1from
WhereisFff:fff/1.21.1-fix

Conversation

@WhereisFff

Copy link
Copy Markdown
Contributor
  • 补齐跨越 0° 的扇区命中判定,鼠标从左上方进入正上方选区时立即切换,无需转到 0°

- 补齐跨越 0° 的扇区命中判定
- 鼠标从左上方进入正上方选区时立即切换,无需转到 0°
@Gugle2308

Copy link
Copy Markdown

已完成审查。以下是审查意见(直接发布到 PR 评论区):


代码审查摘要 — PR #115

操作: opened
范围: 1 个文件(1 Java / +5 −3)/ 与 Anvil-Dev/AnvilLib API 报告的 changed_files=1 一致
目标分支: dev/1.21.1 ← fff/1.21.1-fix

🔍 根因确认(修复方向正确)

原表达式(WheelWidget.java:632-636 区域):

(section.angleStart > section.angleEnd && rotation >= section.angleStart
    || rotation >= section.angleStart && rotation <= section.angleEnd)

&& 优先级高于 ||,等价于 (start > end && rot >= start) || (rot >= start && rot <= end)。当 start > end(跨越 0° 的扇区)时第二个子句恒为 false,整体退化成 rotation >= section.angleStart —— 正上方扇区 [2π−h, h] 只有 [2π−h, 2π](右侧那半边)能被命中,[0, h)(左上那半边)永远无命中。诊断准确。

数值复刻 checkMousePos 逻辑、绕轮盘 3600 个方向采样验证:

扇区数 旧代码盲区(rotation 角) 盲区占比 新代码未命中样本
2 0.1° – 90.0° 25% 0
4 0.1° – 44.9° 12.5% 0
6 0.1° – 30.0° 8.3% 0
8 0.1° – 22.5° 6.25% 0

⚠️ 影响比标题描述更严重(不只是「延迟」)

盲区里循环不命中任何扇区,但代码不重置 currentSectionIndex,于是保留上一个扇区的值:

  • WheelScreen.java:140triggerSelectedOrClose()getCurrentSectionIndex()page.slot(selectedIndex)松手/确认时会触发上一个悬停过的条目(选错项),高亮也停在上一个扇区;
  • 若刚打开轮盘首次悬停就落在盲区,rebuildWheelWidget()clearSelection() 置的 −1 一直保持 → 直接走 onClose()(无声关闭)。

即这是功能性 bug(误触发/无响应),不是纯粹的手感延迟。修复后两种表现都消失。建议同步修正 PR 标题(见末尾)。

🟢 修复正确性

新条件 = 环形区间 [angleStart, 2π] ∪ [0, angleEnd],与文件既有的「跨越 0°」约定完全一致:renderSeparatorRing(L748)与 renderSelection(L844)用 normalizePositiveAngle(angleEnd - angleStart) 计算弧长,本就把 start > end 当作跨 0° 扇区处理。本次修改让命中判定与渲染口径统一,这是最值得肯定的点。语义等价性也已逐支验证:非跨越分支未变,跨越分支只补了 [0, angleEnd] 一段,不产生新的误命中(边界等值处的双命中是既有 tie-break 行为,非本 PR 引入)。

⚠️ 相邻边界(建议顺手处理)

angleStart > section.angleEnd 无法覆盖整圆单扇区sections.size() == 1detectionStartdetectionEnd 都是 rot + 180°(mod 2π 后相等),wrapped = false → 条件变为 rot >= a && rot <= a → 永远不命中,该页轮盘 index 恒为 −1(永不可用)。

建议判定改用 angleStart >= angleEnd(不加 =):s == erotation >= s || rotation <= e 恒真,恰好等于整圆语义,零额外分支。

💡 建议

  • 归一化口径不一致(L631 vs L634)mouseAngleRad 取了 rotation % TAU,但循环用的是未归一化的 rotationrotation ∈ [0, 2π],仅当 x == 0 && y < 0 时取到 2π≠0)。控件宽度为偶数时鼠标正好在正上方中线是可达的:此时箭头(由 mouseAngleRad 派生)指向正上方,但如果该位置的扇区是「从 0° 起算的非跨越扇区」(如 degreeOffsetAngle 取半扇区宽度),反而不会被选中。建议循环前统一 rotation %= TAU;——对跨越扇区语义无影响(2π→0 仍由 rotation <= angleEnd 命中),但能消除这类边界不一致。
  • 可测性:命中判定建议抽成 private static boolean containsAngle(float start, float end, double angle)module.util 已有 ShapeUtilJoinTimingTest 先例)。当前 module.wheelsrc/test,这类角度边界逻辑抽出来后即可做 0° 边界/整圆边界单测。
  • 三元表达式 containsRotation 命名清晰、注释与文件既有中文注释风格一致;选择动效由 L815-825 向 currentAngle 插值,无需额外更新 selectionEffectPos,改动无副作用。

📋 声称验证表

声称 状态 证据
补齐跨越 0° 的扇区命中判定 L634-636 三元分支,旧 rotation >= start 退化语义已被替换
鼠标从左上方进入正上方选区时立即切换,无需转到 0° 模拟盲区由 45°/22.5°/30°(n=4/8/6)收缩为 0
无越界改动 仅 WheelWidget.java 1 文件,+5/−3

🧪 测试建议

被测目标 推荐场景 优先级
containsAngle(start, end, angle) 跨 0° 扇区两段(angle≈0+angle≈2π−)均命中 🔴
同上 边界等值(angle == start / == end)与 start >= end(整圆) 🟡
checkMousePos x == 0 && y < 0(rotation 恰为 2π)与 x < 0 单侧接近 0° 时的选中项一致性 🟡

结论: APPROVE(建议合并) —— 修复正确、最小化、与渲染口径一致,并修掉了一个真实的功能性 bug(盲区内误触发上一个条目)。上面的 >= 整圆边界与 rotation 归一化可作为可选后续改进,不阻塞合并。

关于 CI: mergeable_state: unstable 是多个 build-l0 任务仍在 in_progress(未失败),非构建错误。

标题建议: 现有标题「修复轮盘顺时针切换至正上方选区延迟的问题」低估了影响(实际会误触发上一个条目)且缺少英文标题,建议改为:

Fix wheel sector hit test across 0° 修复轮盘跨越 0° 扇区的命中判定

(本次 gh auth status 显示 /opt/data/home/.config/gh/hosts.yml 中 Gugle2308 的 token 已失效,未执行 gh pr edit;如需我改请先重新 gh auth login。)


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown

💾 Self-improvement review: Skill updated · Patched SKILL.md in skill 'coordinate-transform-pr-review' (1 replacement).

@Gugle2308

Copy link
Copy Markdown

🌿 Roseau API Breaking Change Report

Module Status Breaking Changes
codec ✅ Compatible 0
collision ✅ Compatible 0
config ✅ Compatible 0
integration ✅ Compatible 0
moveable-entity-block ✅ Compatible 0
network ✅ Compatible 0
rendering ⚪ Skipped
space-select ✅ Compatible 0
font ✅ Compatible 0
util ✅ Compatible 0
explosion ✅ Compatible 0
rpc ✅ Compatible 0
multiblock ✅ Compatible 0
recipe ✅ Compatible 0
registrum ✅ Compatible 0
sync ✅ Compatible 0
wheel ✅ Compatible 0
main ✅ Compatible 0

Full CSVs: see the Artifacts section of this workflow run.

@PigeonNian
PigeonNian merged commit 712b747 into Anvil-Dev:dev/1.21.1 Sep 11, 2026
38 checks passed
@Gugle2308

Copy link
Copy Markdown

PR #115(Anvil-Dev/AnvilLib)状态为 closed,按 webhook 审查约定(closed/labeled → 停止),不生成审查意见、不发表评论。

如需对已合并/关闭的改动做回顾性审查,请重新触发 open/synchronize 事件,或直接告诉我,我再拉取 diff 分析。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants