我如何简化这个数学方法(旋转到步骤)
How do i simplify this math method (rotations to steps)
所以我正在为统一创建一个捕捉工具包,我想通过特定值来限制旋转的捕捉增量。
您可以按 2.5、5、10、15、30、45 和 90 的增量捕捉旋转(这样当用户旋转对象时,它只会旋转该增量值)。
我有一个带有滑块的工具栏,滑块有 7 个步长(0-6),每个步长代表一个旋转。所以我需要将旋转转换为步数。
代码和功能已经完成,但是将旋转转换为步进和反之的函数又长又难看。可以simplify/shorten吗?
步数和旋转:
Step
Rotation
0
2.5
1
5
2
10
3
15
4
30
5
45
6
90
代码:
private float ConvertFromStepToRotation(int step)
{
switch (step)
{
case 0:
return 2.5f;
case 1:
return 5;
case 2:
return 10;
case 3:
return 15;
case 4:
return 30;
case 5:
return 45;
case 6:
return 90;
}
return 15;
}
private int ConvertFromRotationToStep(float rotation)
{
if (rotation >= 90)
{
return 6;
}
if (rotation >= 45)
{
return 5;
}
if (rotation >= 30)
{
return 4;
}
if (rotation >= 15)
{
return 3;
}
if (rotation >= 10)
{
return 2;
}
if (rotation >= 5)
{
return 1;
}
if (rotation >= 2.5f)
{
return 0;
}
return 2;
}
没什么大不了的,只是让我唠叨应该有更好的方法
编辑:尝试让 table 正常工作
看来我们可以用数组让它更漂亮。
ConvertFromStepToRotation
是一个明显的候选者:我们只是将索引转换为相应的值,因此我们可以使用它来索引值数组。
ConvertFromRotationToStep
稍微有点棘手,但我们可以向后遍历数组,return 是 rotation >= steps[i]
.
的第一个索引
private static readonly float[] steps = new[] { 2.5f, 5f, 10f, 15f, 30f, 45f, 90f };
private float ConvertFromStepToRotation(int step)
{
if (step < steps.Length)
{
return steps[step];
}
return 15f;
}
private int ConvertFromRotationToStep(float rotation)
{
for (int i = steps.Length - 1; i >= 0; i++)
{
if (rotation >= steps[i])
{
return i;
}
}
return 2;
}
对于一个很好的偏执解决方案,步骤 s
可以通过 one-liner
从角度 a
获得
s = floor(log(a)/log(√3)-1.5).
在你不能依赖数组索引的情况下(或者你想更好地控制哪个步骤引用哪个旋转),你可以选择将关系存储在字典中:
//using System.Collections.Generic;
private Dictionary<int, float> rotationForStep = new()
{
[0] = 2.5f,
//...
[6] = 90
};
并实施您的方法,例如如下:
//using System.Linq;
private float ConvertFromStepToRotation(int step)
{
if (rotationForStep.TryGetValue(step, out float rotation))
{
return rotation;
}
return 15;
}
private int ConvertFromRotationToStep(float rotation)
{
if (rotationForStep.Values.Any(v => v <= rotation))
{
return rotationForStep
.Where(r => r.Value <= rotation)
.MaxBy(r => r.Value)
.Key;
}
return 2;
}
或者最后一种方法:
//using System.Linq;
private int ConvertFromRotationToStep(float rotation)
{
var possibleRotations = rotationForStep.Where(r => r.Value <= rotation);
if (possibleRotations.Any())
{
return possibleRotations.MaxBy(r => r.Value).Key;
}
return 2;
}
所以我正在为统一创建一个捕捉工具包,我想通过特定值来限制旋转的捕捉增量。
您可以按 2.5、5、10、15、30、45 和 90 的增量捕捉旋转(这样当用户旋转对象时,它只会旋转该增量值)。
我有一个带有滑块的工具栏,滑块有 7 个步长(0-6),每个步长代表一个旋转。所以我需要将旋转转换为步数。
代码和功能已经完成,但是将旋转转换为步进和反之的函数又长又难看。可以simplify/shorten吗?
步数和旋转:
Step | Rotation |
---|---|
0 | 2.5 |
1 | 5 |
2 | 10 |
3 | 15 |
4 | 30 |
5 | 45 |
6 | 90 |
代码:
private float ConvertFromStepToRotation(int step)
{
switch (step)
{
case 0:
return 2.5f;
case 1:
return 5;
case 2:
return 10;
case 3:
return 15;
case 4:
return 30;
case 5:
return 45;
case 6:
return 90;
}
return 15;
}
private int ConvertFromRotationToStep(float rotation)
{
if (rotation >= 90)
{
return 6;
}
if (rotation >= 45)
{
return 5;
}
if (rotation >= 30)
{
return 4;
}
if (rotation >= 15)
{
return 3;
}
if (rotation >= 10)
{
return 2;
}
if (rotation >= 5)
{
return 1;
}
if (rotation >= 2.5f)
{
return 0;
}
return 2;
}
没什么大不了的,只是让我唠叨应该有更好的方法
编辑:尝试让 table 正常工作
看来我们可以用数组让它更漂亮。
ConvertFromStepToRotation
是一个明显的候选者:我们只是将索引转换为相应的值,因此我们可以使用它来索引值数组。
ConvertFromRotationToStep
稍微有点棘手,但我们可以向后遍历数组,return 是 rotation >= steps[i]
.
private static readonly float[] steps = new[] { 2.5f, 5f, 10f, 15f, 30f, 45f, 90f };
private float ConvertFromStepToRotation(int step)
{
if (step < steps.Length)
{
return steps[step];
}
return 15f;
}
private int ConvertFromRotationToStep(float rotation)
{
for (int i = steps.Length - 1; i >= 0; i++)
{
if (rotation >= steps[i])
{
return i;
}
}
return 2;
}
对于一个很好的偏执解决方案,步骤 s
可以通过 one-liner
a
获得
s = floor(log(a)/log(√3)-1.5).
在你不能依赖数组索引的情况下(或者你想更好地控制哪个步骤引用哪个旋转),你可以选择将关系存储在字典中:
//using System.Collections.Generic;
private Dictionary<int, float> rotationForStep = new()
{
[0] = 2.5f,
//...
[6] = 90
};
并实施您的方法,例如如下:
//using System.Linq;
private float ConvertFromStepToRotation(int step)
{
if (rotationForStep.TryGetValue(step, out float rotation))
{
return rotation;
}
return 15;
}
private int ConvertFromRotationToStep(float rotation)
{
if (rotationForStep.Values.Any(v => v <= rotation))
{
return rotationForStep
.Where(r => r.Value <= rotation)
.MaxBy(r => r.Value)
.Key;
}
return 2;
}
或者最后一种方法:
//using System.Linq;
private int ConvertFromRotationToStep(float rotation)
{
var possibleRotations = rotationForStep.Where(r => r.Value <= rotation);
if (possibleRotations.Any())
{
return possibleRotations.MaxBy(r => r.Value).Key;
}
return 2;
}