我有几个类遵循相同的基本概念来处理单位。
以下是单元测试中使用的一个简单示例:
[Test()]
public void Angle_MathOperatorTest()
{
Angle a1 = new Angle(AngleType.Degree, 360);
Angle a2 = new Angle(AngleType.Radian, Math.PI * 2);
Angle addedAngle = a1 + a2;
addedAngle.Degrees.ShouldBeEquivalentTo(720);
Angle subtractedAngle = a1 - a2;
subtractedAngle.Radians.ShouldBeEquivalentTo(0);
}
我已经制作了几个类,这个类演示了Angle Class,涵盖了其他基本单元类型。
向我揭示我遇到精度问题的特定类是使用处理长度单位的类:Dimension
我帮助使用这个Dimension类作为基本单元类型构建了一个基本的Geometry Library。例如,这是Point类:
public class Point
{
public Dimension X;
public Dimension Y;
public Dimension Z;
}
线条和其他形状具有像Dimensions这样的属性,以及使用此Point Class构建的端点。
当我试图判断这些线是否全部平行时,问题变得明显。就像在这个函数中一样:
/// <summary>
/// checks to see whether every line is parallel
/// </summary>
/// <param name="passedLines">passed List of Lines</param>
/// <returns></returns>
public static bool AreAllParallel(this List<Line> passedLines)
{
for (int i = 0; i < passedLines.Count - 1; i++)
{
if (!passedLines[i].IsParallelTo(passedLines[i + 1]))
{
return false;
}
}
return true;
}
它经常会返回false,因为它检查的精度太高。在使用Points和line进行Rotations和Translations之后,当我希望它返回true时,舍入加起来足以使该函数返回false。
所以:
以下哪一组选择是正确/更好的选择?
IsParallelTo
等函数,查看相对较近的数字(例如在.0001英寸范围内)如果(Math.Abs(thing.x - thing2.x)&lt; .0001)
if(Math.Abs(thing.x - thing2.x)&lt; Properties.AcceptedDeviationConstant)
我可以使用相同的策略
//inside Dimension Equals
public override bool Equals(object obj)
{
return (Math.Abs(this.Inches - ((Dimension)(obj)).Inches)) < Constants.AcceptedEqualityDeviationConstant;
}
它看起来真的很像,但上面的内容更容易理解
return(Math.Abs(this.GetValue(this.InternalUnitType) - ((Dimension)(obj))。GetValue(this.InternalUnitType)))&lt; Constants.AcceptedEqualityDeviationConstant;
或者最后,我的最后一个想法是将我的单元类中的所有内容替换为Decimal
的基本单位而不是Double
(Dimension,Angle等)到Decimal以及某种方式(在研究之后)在它上面)弄清楚这是否会有所帮助。
我应该如何以及在哪里提高班级平等操作的精确性?
答案 0 :(得分:0)
如果e1
是第一行的方向而e2
是第二行的方向,那么检查它们是否在θ(弧度)的斜率公差内是平行的,执行以下操作(伪代码):
bool is_parallel = |Cross(e1,e2)| <= |e1|*|e2|*Cos(θ)
其中|v|
是矢量幅度,Cross()
是矢量叉积。