前言: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²)
===================================================================================================================