日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

向量法计算多边形面积

發(fā)布時間:2023/12/14 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 向量法计算多边形面积 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

  計算多邊形面積的方法為將多邊形分解成多個三角形,然后把這些三角形的面積相加。三角形面積為兩邊向量叉積除以2。

  這是Java代碼,目前是第3版?,已經(jīng)盡可能優(yōu)化了,相比初版有25%的性能提升。

/*** 平面多邊形面積算法3,用原點為基點(不需要從圖形邊線上取點)<br/>* 多計算一條線段,但減少了每一步的兩次減法(起于原點的向量等于節(jié)點的坐標(biāo)),使誤差減小,每一步的計算量減少。* * @return 正方向(x軸向y軸旋轉(zhuǎn)方向)圈成的面積(如果有反方向的圈,則面積會被抵消,導(dǎo)致結(jié)果小于直觀觀測的面積或為負(fù)數(shù))*/private static final double getPolygonAreaMethodC(double... points) {if (points.length < 6) {// 無法構(gòu)成多邊形return 0;}final int pointArrayLength = points.length & (~1);// final int pointCount = pointArrayLength / 2;double area = 0.0;double dx1, dy1;double dx2, dy2;// 從原點到該點的向量dx1 = points[pointArrayLength - 2];dy1 = points[pointArrayLength - 1];for (int i = 0; i < pointArrayLength;) {// 從原點到該點的向量dx2 = points[i++];dy2 = points[i++];// 三角形的面積2倍,平行四邊形面積。為提高性能,不在循環(huán)中進行面積減半final double subArea = dx1 * dy2 - dx2 * dy1;// 由jvm進行智能內(nèi)聯(lián),分出這一步不會影響性能area += subArea;// 向量傳遞dx1 = dx2;dy1 = dy2;}// 最后統(tǒng)一除以2,提高性能return area / 2;}

  除了可以用來計算面積,還可以進行分布式計算π。把半徑R的圓分解成很多邊的多邊形,每臺計算機只計算其中的一部分。然后將每臺計算機算出的面積相加得到面積S。π=S/(R^2)。這只是一種用法,事實上并不建議用此方法計算π。最好的辦法仍然是可迭代的,所以分布式計算π并沒有優(yōu)勢。

  下面是C++的版本,也是初版,作為參考。

/*** 平面多邊形面積** @return*/ double getPolygonArea(double *points, int length) {if (length < 6) {// 無法構(gòu)成多邊形return 0;}double area = 0.0;double x0 = points[0], y0 = points[1];double dx1, dy1;double dx2, dy2;dx1 = points[2] - x0;dy1 = points[3] - y0;for (int i = 4; i < length - 1; i += 2) {dx2 = points[i] - x0;dy2 = points[i + 1] - y0;double subArea = (dx1 * dy2 - dx2 * dy1) / 2.0;area += subArea;dx1 = dx2;dy1 = dy2;}return area; }

Java并發(fā)版本(有依賴項,不可直接使用)。

依賴項1:ParallelTask.parallelFor其實是線程池。第一個參數(shù)0代表WorkSteal線程池。第二個參數(shù)代表Lambda執(zhí)行的次數(shù),一般取CPU核心數(shù)。Lambda的參數(shù)threadOrder代表此Lambda所在線程啟動的順序。靜態(tài)的方法parallelFor代表內(nèi)部生成線程池,并在返回之前關(guān)閉和等待線程池任務(wù)結(jié)束。ParallelTask是一個實現(xiàn)了十幾種動態(tài)與靜態(tài)parallelFor的大文件,不方便上傳。

依賴項2:StaticSystemUtils.getCPUCoreCount就是Runtime.avaliableProcesses()。StaticSystemUtils是一個獲取系統(tǒng)信息的大文件,不方便上傳。

依賴項3:StaticMathUtils.sum就是一個求和函數(shù)。StaticMathUtils是一個包含數(shù)十種算術(shù)方法,幾千行的大文件,不方便上傳。

/*** 平面多邊形面積算法3,用原點為基點(不需要從圖形邊線上取點)<br/>* 多計算一條線段,但減少了每一步的兩次減法(起于原點的向量等于節(jié)點的坐標(biāo)),使誤差減小,每一步的計算量減少。* * @return 正方向(x軸向y軸旋轉(zhuǎn)方向)圈成的面積(如果有反方向的圈,則面積會被抵消,導(dǎo)致結(jié)果小于直觀觀測的面積或為負(fù)數(shù))*/public static final double getPolygonAreaParallel(double... points) {if (points.length < 6) {// 無法構(gòu)成多邊形return 0;}final int pointArrayLength = points.length & (~1);final int pointCount = pointArrayLength / 2;double area = 0.0;final int taskCount = Math.min(StaticSystemUtils.getCPUCoreCount(), pointCount);final double[] eachArea = new double[taskCount];ParallelTask.parallelFor(0, taskCount, threadOrder -> {final int from = (int) ((long) threadOrder * pointArrayLength / taskCount) & (~1);final int to = (int) ((long) (threadOrder + 1) * pointArrayLength / taskCount) & (~1);double threadArea = 0.0;double dx1, dy1;double dx2, dy2;// 從原點到該點的向量if (threadOrder == 0) {dx1 = points[pointArrayLength - 2];dy1 = points[pointArrayLength - 1];} else {dx1 = points[from - 2];dy1 = points[from - 1];}for (int i = from; i < to;) {// 從原點到該點的向量dx2 = points[i++];dy2 = points[i++];// 三角形的面積2倍,平行四邊形面積。為提高性能,不在循環(huán)中進行面積減半final double subArea = dx1 * dy2 - dx2 * dy1;// 由jvm進行智能內(nèi)聯(lián),分出這一步不會影響性能threadArea += subArea;// 向量傳遞dx1 = dx2;dy1 = dy2;}eachArea[threadOrder] = threadArea;});area = StaticMathUtils.sum(eachArea);// 最后統(tǒng)一除以2,提高性能return area / 2;}

?

總結(jié)

以上是生活随笔為你收集整理的向量法计算多边形面积的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。