我正在尝试创建一个径向FAB菜单,并定义所有圆的位置,我有一个算法在理论上可以正常工作,但是当我实际运行它时,Y值给了我一些奇怪的东西。 。我会尽快发布代码
请注意,除非您需要参考值的含义,否则这部分并不是很重要
public class FABContainer : AbsoluteLayout
{
public static int NUMBER_FOR_RING = 1;
public static double ANGLE_INCREMENT = 360.0 / ((double)NUMBER_FOR_RING);
public static double CENTER_RADIUS = 100;
public static double WIDTH_MOD = 0.9;
public FABContainer()
{
this.BackgroundColor = Color.Transparent;
FAB fab = new FAB();
List<InternalFAB> internals = new List<InternalFAB>();
internals.Add(new InternalFAB(this, internals.Count)
{
});
this.Children.Add(fab);
foreach(InternalFAB f in internals) { this.Children.Add(f); };
}
}
public partial class FAB : SuaveControls.Views.FloatingActionButton
{
public FAB()
{
this.HeightRequest = FABContainer.CENTER_RADIUS;
this.WidthRequest = FABContainer.CENTER_RADIUS * FABContainer.WIDTH_MOD;
Debug.WriteLine($"CREATING NEW CENTER WITH W: {this.WidthRequest} H: {this.HeightRequest}");
this.Image = "Edit_Icon.png";
this.BackgroundColor = Color.Transparent;
this.CornerRadius = (int)this.HeightRequest;
}
}
internal class InternalFAB : SuaveControls.Views.FloatingActionButton
{
public static double DIST = 5;
public EventHandler OnClicked;
public static double radius = 80;
public InternalFAB(FABContainer container, int count)
{
this.HeightRequest = (radius);
this.WidthRequest = (radius * FABContainer.WIDTH_MOD * 0.95);
this.BackgroundColor = Color.Transparent;
int index = count + 1;
double AngleDistortion = ((double)index) * FABContainer.ANGLE_INCREMENT;
double xpos = (DIST + this.WidthRequest) * (Math.Cos((Math.PI / 180.0) * AngleDistortion));
double ypos = (DIST + this.HeightRequest) * (Math.Sin((Math.PI / 180.0) *AngleDistortion));
Debug.WriteLine($"CREATING NEW INTERNAL AT: {xpos},{ypos} from distortion {AngleDistortion}");
this.TranslationX = xpos;
this.TranslationY = ypos;
}
}
没关系,但这是使用Xamarin。本质上,实际上很重要并给我带来问题的部分是以下部分:
double AngleDistortion = ((double)index) * FABContainer.ANGLE_INCREMENT;
double xpos = (DIST + this.WidthRequest) * (Math.Cos((Math.PI / 180.0) * AngleDistortion));
double ypos = (DIST + this.HeightRequest) * (Math.Sin((Math.PI / 180.0) *AngleDistortion));
Debug.WriteLine($"CREATING NEW INTERNAL AT: {xpos},{ypos} from distortion {AngleDistortion}");
无论出于何种原因,Y值都将返回为 -2.08183080149804E-14 ,而不是“完美”情况下应返回的0。我遍历了我的代码,以试图发现错误无济于事。
如果您需要有关我的代码的更多说明,我会立即告诉您。
答案 0 :(得分:0)
乘以85对这个问题并不重要,因此我将其放在一边,而仅研究(有效)Math.Sin(Math.PI * 2)
。其结果是在我的计算机上-2.44921270764475E-16
。
当然,浮点算术不是精确的,但结果并不是胡扯。这里发生的是,在x = 2pi附近,sin(x)≈x-2pi。但是,Math.Sin(Math.PI * 2)
不会不精确评估2pi的正弦,它不能,2pi是先验的,绝对不能表示为浮点数。正弦输入已经稍微“关闭”,并且具有一些值v=fl(2pi)
,其中fl
将值四舍五入到最接近的可表示浮点数。然后sin(v) ≈ v - 2pi
,因为v
接近2pi。
因此Math.Sin(Math.PI * 2)
的结果应大致代表我们作为参数传递的2 pi与 real 2 pi的距离。 Math.PI * 2
在我的机器上的准确值为6.28318530717958623199592693708837032318115234375,即-2.4492935982947063544521318645500 ...×10 ^ -16距 real 2 pi,这非常接近到先前的-2.44921270764475E-16
值。它不完全在那儿,但足够接近以表明它不仅仅是任意的。