C# 定積分求周長&面積原理 代碼實現

前言:html

         前些日子,由於工做緣由,接觸到了求解曲線周長,真的是搞了好久,學生時代真的很簡單,可是現在的我來講,忘記了....不少人跟我應該同樣。函數

          因此來鞏固增強一下記憶。一開始的時候,求周長嘛,找公式唄,什麼matlab呀,亂七八糟的,暈,最後找到了可能還不能知足項目的需求,由於可能計算量過大。(我就是這樣子的,靈活性相對較低)工具

          還有就是明明本身能夠用代碼實現,爲何非要插件,工具吶,這麼不自信的?測試

          因此,「一怒之下」,本身去看了一下定積分求周長的原理,本身仍是用代碼來實現吧。spa

(如下內容純是我的這段時間的理解,若是有錯誤的,歡迎指正出來。)插件

 

首先須要說說兩個概念,曲線和周長,由於咱們要求他們嘛。code

曲線:

  這個世界,有曲線嗎?個人回答是,沒有。那...這...曲線是由無數個直接拼接而成。再準確的說無數個很短的曲線拼接而成。htm

(若是您完全理解了這句話,後面就不用看了,基本就沒了。)blog

 

面積:

  與周長的概念相似,沒有正方形,沒有圓形。只有三角形,全部的圖形都是三角形拼接而成。而兩個三角形拼成長方形,而咱們的面積是由無數個長方形,拼接而成。源碼

  

                (定積分原理的參考圖)

 

源碼實現: 

double GetLength(float start,float end)
        {
            double sumLength = 0;

            float eachX = (end - start) / testCount; 
            for (int i = 1; i < testCount;i++ )
            {
              
                double curY =ArcFunction(start+eachX*i);
                double previousY = ArcFunction(start+eachX*(i-1));
                //根據c²=a²+b²
                double curLength = Math.Sqrt(Math.Pow(eachX, 2) + Math.Pow(curY - previousY, 2));
                sumLength += curLength;
            }
                return sumLength;
        }


   解釋:

             testCount,即自定義的測試數量,能夠理解爲精細度,值越大,計算量越大,數據越準確,這個可看你項目需求精細度,經過該變量

可在實現最少的計算量狀況,實現你要的效果。

    eachX,就是你的曲線被分紅N份,每份的長度。

    curY,當前點的y軸份量

    previousY,上一個點的y軸份量,

    curLength,即如圖   

    

                                                      

                  (剩餘的部分,代碼裏面含解釋,我的喜歡放在源碼裏面,原生的,純24k原創)   

 1     int testCount = 1000; //所謂的測試細緻度吧,可動態調控,你本身掌握。
 2         /// <summary>
 3         /// 經過已知周長,獲取x軸的份量
 4         /// </summary>
 5         /// <param name="length"></param>
 6         /// <returns></returns>
 7         double GetRateXByLength(double length)
 8         {
 9             float eachX = 1.0f;
10             for (int i = 1; i < testCount; i++)
11             {
12                 double curY = ArcFunction(eachX * i);
13                 double previousY = ArcFunction(eachX * (i - 1));
14                 double curLength = Math.Sqrt(Math.Pow(eachX, 2) + Math.Pow(curY - previousY, 2));
15                 length -= curLength;
16                 if(length<=0)
17                 {
18                     return i * eachX;
19                 }
20             }
21             return testCount * eachX;
22         }
23             
24         
25       
26 
27 
28         /// <summary>
29         /// start到end範圍內的面積
30         /// </summary>
31         /// <param name="start"></param>
32         /// <param name="end"></param>
33         /// <returns></returns>
34         double GetArea(float start,float end)
35         {
36             double sumAera = 0;
37 
38             float eachX = (end - start) / testCount;
39             for (int i = 1; i < testCount; i++)
40             {
41                 double curY = ArcFunction(start + eachX * i);
42                 //面積 = 長*寬
43                 double curAera = curY * eachX;
44                 sumAera += curAera;
45             }
46             return sumAera;
47         }
48 
49 
50 
51         /// <summary>
52         /// 經過已知面積,獲取x軸份量
53         /// </summary>
54         /// <param name="aera"></param>
55         /// <returns></returns>
56         double GetRateXByAera(double aera)
57         {
58             float eachX = 1.0f;
59             for (int i = 1; i < testCount; i++)
60             {
61                 double curY = ArcFunction(eachX * i);
62                 double curAera = curY * eachX;
63                 aera -= curAera;
64                 if(aera<=0)
65                 {
66                     return i * eachX;
67                 }
68             }
69             return testCount*eachX;
70         }
71 
72 
73 
74         /// <summary>
75         /// 經過x份量,得出y的值。(好像意義不大,可是好像可能有些人不是很理解,寫給某些人看的,一目瞭然)
76         /// </summary>
77         /// <param name="x"></param>
78         /// <returns></returns>
79         double GetYByX(float x)
80         {
81             return ArcFunction(x);
82         }
83 
84 
85         /// <summary>
86         /// 核心控制函數。
87         /// </summary>
88         /// <param name="x"></param>
89         /// <returns></returns>
90         double ArcFunction(float x)
91         {
92             return Math.Pow(x, 2); //這邊我用冪函數來測試。各位爺能夠換其餘函數啊。
93 
94             //注:若是對曲線靈活性要求很高,推薦使用貝塞爾曲線。
95             //詳情可參考:
96         }

 

 

補充:這邊,我對貝塞爾曲線作一下補充吧。由於我由於什麼冪函數,指數函數遇到的肯,由於這些函數畢竟還不是那麼靈活,都具備必定「規律」。

貝塞爾曲線的靈活,受6個參數控制,三個點嘛。(二維空間)

 詳情可參考這篇:http://www.sohu.com/a/118656687_466876

 

 

======================================= 2018年9月3日補充================================================================

        可使用第三方插件:開源Math.Net進行數值積分。

        參考:https://www.cnblogs.com/asxinyu/p/4301017.html     

public static double OnClosedInterval(Func<double, double> f, double intervalBegin, double intervalEnd);

 

 

void Start () {
        var result = Integrate.OnClosedInterval(TestFunc, 0, 24);
         Debug.Log(result);
	}

    double TestFunc(double x)
    {
        return x * x;
    }

 

  可是上述的result爲面積,也是dy。

 

  再根據定積分求弧長公式:

              

       即:弧長 =  √(1+result²)    

===================================================================================================================

相關文章
相關標籤/搜索