簡體   English   中英

Math.Sin給我怪異的價值觀

[英]Math.Sin giving me weird values

我正在嘗試創建一個徑向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。 我遍歷了我的代碼,以試圖找到錯誤,但沒有結果。

如果您需要有關我的代碼的更多說明,我會立即告訴您。

您正在使用double進行浮點算術運算 意味着您所做的一切都是近似的。 如果您想要確切的值,則C#可能不是您的首選語言。 Mathematica支持這些類型的值。

對於這個問題,乘以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與實際 2 pi的距離。 根據Wolfram Alpha ,我的機器上Math.PI * 2的准確值為6.28318530717958623199592693708837032318115234375 ...與實際 2 pi相比是-2.4492935982947063544521318645500 ...×10 ^ -16,非常接近-2.44921270764475E-16值從以前開始。 它不完全在那兒,但足夠接近以表明它不僅僅是任意的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM