fix: 修复滑动选择方向错位与边界/圆环外不命中(物理像素换算 + 按方向就近命中)

This commit is contained in:
2026-08-30 16:24:40 +08:00
parent ad98eb18dc
commit e4324f29cc
10 changed files with 242 additions and 13 deletions
@@ -0,0 +1,64 @@
using System.Windows;
using OneClickRun.Helpers;
using Xunit;
namespace OneClickRun.Tests;
/// <summary>滑动选择:按方向角选取最近扇形的行为测试</summary>
public class WheelGeometrySwipeTests
{
private const double InnerR = 70;
private static readonly Point Center = new(300, 300);
private static Point At(double angleDeg, double radius) =>
WheelGeometry.PointOnCircle(Center, radius, angleDeg * Math.PI / 180);
[Theory]
[InlineData(4, -90, 0)] // 上 → 扇形0
[InlineData(4, 0, 1)] // 右 → 扇形1
[InlineData(4, 90, 2)] // 下 → 扇形2
[InlineData(4, 180, 3)] // 左 → 扇形3
[InlineData(3, -90, 0)] // 上 → 扇形0
[InlineData(3, 0, 0)] // 右 → 扇形0(3:00 位于扇形0 区域内)
[InlineData(3, 90, 1)] // 下 → 扇形1
[InlineData(3, 180, 2)] // 左 → 扇形2
[InlineData(12, 15, 3)] // 12 扇区:15° 方向 → rel=105°,span=30° → 扇形3
public void PicksSectorByDirection(int count, double angleDeg, int expected)
{
var point = At(angleDeg, (InnerR + 220) / 2);
Assert.Equal(expected, WheelGeometry.PickSectorByAngle(point, Center, InnerR, count));
}
[Fact]
public void CenterHubReturnsNull()
{
Assert.Null(WheelGeometry.PickSectorByAngle(Center, Center, InnerR, 4));
Assert.Null(WheelGeometry.PickSectorByAngle(At(45, InnerR - 5), Center, InnerR, 4));
}
[Fact]
public void BeyondOuterRadiusStillPicksByDirection()
{
// 快速滑动滑出圆环外:仍按方向命中
Assert.Equal(0, WheelGeometry.PickSectorByAngle(At(-45, 800), Center, InnerR, 4));
Assert.Equal(2, WheelGeometry.PickSectorByAngle(At(135, 2000), Center, InnerR, 4));
}
[Fact]
public void GapAndBoundaryPickNearestSector()
{
// 4 扇区:89°/91° 位于 90° 边界两侧的间隙内,应就近归属扇形1/扇形2
Assert.Equal(1, WheelGeometry.PickSectorByAngle(At(89, 145), Center, InnerR, 4));
Assert.Equal(2, WheelGeometry.PickSectorByAngle(At(91, 145), Center, InnerR, 4));
// 恰好正下方:边界平局 → 扇形2
Assert.Equal(2, WheelGeometry.PickSectorByAngle(At(90, 145), Center, InnerR, 4));
}
[Fact]
public void SingleSectorPicksAnyDirection()
{
Assert.Equal(0, WheelGeometry.PickSectorByAngle(At(0, 300), Center, InnerR, 1));
Assert.Equal(0, WheelGeometry.PickSectorByAngle(At(213, 300), Center, InnerR, 1));
Assert.Null(WheelGeometry.PickSectorByAngle(Center, Center, InnerR, 1));
}
}