利用百度API(JavaScript 版)实现在地图上绘制任一多边形,并判断给定经纬度是否在多边形范围内。以及两点间的测距功能

利用百度API(JavaScript 版)实现在地图上绘制任一多边形,并判断给定经纬度是否在多边形范围内。以及两点间的测距功能。

[javascript] view plain copy
 
  1. 绘制多边形(蓝色),折线轨迹(红色)效果图:  
[javascript] view plain copy
 
  1. <img src="http://img.blog.csdn.net/20150915193750707?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />  

判断点范围,测距:

html代码:

[html] view plain copy
 
  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4.     <meta http-equiv="Content-Type" content="text/html; charset=gbk" />  
  5.     <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />  
  6.     <style type="text/css">  
  7.         body, html{ 100%;height: 100%;margin:0;font-family:"微软雅黑";}  
  8.         #allmap {height:500px;  100%;}  
  9.         #control{100%;}  
  10.     </style>  
  11.     <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=iqgvSM0gddG4NkGXFlawVa6C"></script>      
  12.         <script type="text/javascript" src="GeoUtils.js"></script>  
  13.     <title>设置线、面可编辑</title>  
  14. </head>  
  15. <body>  
  16.     <div id="allmap"></div>  
  17.     <div id="control">  
  18.         <button onclick = "polyline.enableEditing();polygon.enableEditing();">开启线、面编辑功能</button>  
  19.         <button onclick = "polyline.disableEditing();polygon.disableEditing();">关闭线、面编辑功能</button>  
  20.     </div>  
  21. </body>  
  22. </html>  
  23. <script type="text/javascript">  
  24.     // 百度地图API功能  
  25.     var map = new BMap.Map("allmap");  
  26.     map.centerAndZoom(new BMap.Point(106.613922,29.53832), 15);  
  27.     map.enableScrollWheelZoom();  
  28.   
  29.     var polyline = new BMap.Polyline([  
  30.         new BMap.Point(106.612539,29.529602),  
  31.         new BMap.Point(106.607975,29.53177),  
  32.         new BMap.Point(106.610311,29.525862),  
  33.                new BMap.Point(106.60776,29.524008)  
  34.     ], {strokeColor:"red", strokeWeight:2, strokeOpacity:0.5});   //创建折线  
  35.     map.addOverlay(polyline);   //增加折线  
  36.       
  37.     var polygon = new BMap.Polygon([  
  38.         new BMap.Point(106.607477,29.544864),  
  39.         new BMap.Point(106.613572,29.548324),  
  40.         new BMap.Point(106.619357,29.537421),  
  41.         new BMap.Point(106.612988,29.537079),  
  42.         new BMap.Point(106.615359,29.541143)  
  43.     ], {strokeColor:"blue", strokeWeight:2, strokeOpacity:0.5});  //创建多边形  
  44.     map.addOverlay(polygon);   //增加多边形  
  45.   
  46.         var ppoint = new BMap.Point(106.613087,29.540485);  
  47.   
  48.          var result=BMapLib.GeoUtils.isPointInPolygon(ppoint, polygon);  
  49.       
  50.          alert("数字图书馆是否在多边形范围内:"+result);  
  51.   
  52.          var ppoint1 = new BMap.Point(106.614986,29.539876);  
  53.           
  54.         var result1=BMapLib.GeoUtils.isPointInPolygon(ppoint1, polygon);  
  55.   
  56.         alert("乒乓球馆是否在多边形范围内:"+result1+"米");  
  57.   
  58.          var distance =map.getDistance(ppoint, ppoint1);  
  59.         
  60.          alert("The Distance is"+distance);   
  61.           
  62. </script>  

第二步,添加GeoUtils.js文件,代码如下:

[javascript] view plain copy
 
  1. /**   
  2. * @fileoverview GeoUtils类提供若干几何算法,用来帮助用户判断点与矩形、   
  3. * 圆形、多边形线、多边形面的关系,并提供计算折线长度和多边形的面积的公式。    
  4. * 主入口类是<a href="symbols/BMapLib.GeoUtils.html">GeoUtils</a>,   
  5. * 基于Baidu Map API 1.2。   
  6. *   
  7. * @author Baidu Map Api Group    
  8. * @version 1.2   
  9. */      
  10.       
  11. //BMapLib.GeoUtils.degreeToRad(Number)      
  12. //将度转化为弧度      
  13.       
  14. //BMapLib.GeoUtils.getDistance(Point, Point)      
  15. //计算两点之间的距离,两点坐标必须为经纬度      
  16.       
  17. //BMapLib.GeoUtils.getPolygonArea(polygon)      
  18. //计算多边形面或点数组构建图形的面积,注意:坐标类型只能是经纬度,且不适合计算自相交多边形的面积(封闭的面积)      
  19.       
  20. //BMapLib.GeoUtils.getPolylineDistance(polyline)      
  21. //计算折线或者点数组的长度      
  22.       
  23. //BMapLib.GeoUtils.isPointInCircle(point, circle)      
  24. //判断点是否在圆形内      
  25.       
  26. //BMapLib.GeoUtils.isPointInPolygon(point, polygon)      
  27. //判断点是否多边形内      
  28.       
  29. //BMapLib.GeoUtils.isPointInRect(point, bounds)      
  30. //判断点是否在矩形内      
  31.       
  32. //BMapLib.GeoUtils.isPointOnPolyline(point, polyline)      
  33. //判断点是否在折线上      
  34.       
  35. //BMapLib.GeoUtils.radToDegree(Number)      
  36. //将弧度转化为度      
  37.       
  38. /**    
  39. * @namespace BMap的所有library类均放在BMapLib命名空间下   
  40. */      
  41. var BMapLib = window.BMapLib = BMapLib || {};      
  42. (function () {      
  43.       
  44.     /**   
  45.     * 地球半径   
  46.     */      
  47.     var EARTHRADIUS = 6370996.81;      
  48.       
  49.     /**    
  50.     * @exports GeoUtils as BMapLib.GeoUtils    
  51.     */      
  52.     var GeoUtils =      
  53.     /**   
  54.     * GeoUtils类,静态类,勿需实例化即可使用   
  55.     * @class GeoUtils类的<b>入口</b>。   
  56.     * 该类提供的都是静态方法,勿需实例化即可使用。        
  57.     */      
  58.      BMapLib.GeoUtils = function () {      
  59.      }      
  60.       
  61.     /**   
  62.     * 判断点是否在矩形内   
  63.     * @param {Point} point 点对象   
  64.     * @param {Bounds} bounds 矩形边界对象   
  65.     * @returns {Boolean} 点在矩形内返回true,否则返回false   
  66.     */      
  67.     GeoUtils.isPointInRect = function (point, bounds) {      
  68.         //检查类型是否正确      
  69.         if (!(point instanceof BMap.Point) ||      
  70.              !(bounds instanceof BMap.Bounds)) {      
  71.             return false;      
  72.         }      
  73.         var sw = bounds.getSouthWest(); //西南脚点      
  74.         var ne = bounds.getNorthEast(); //东北脚点      
  75.         return (point.lng >= sw.lng && point.lng <= ne.lng && point.lat >= sw.lat && point.lat <= ne.lat);      
  76.     }      
  77.       
  78.     /**   
  79.     * 判断点是否在圆形内   
  80.     * @param {Point} point 点对象   
  81.     * @param {Circle} circle 圆形对象   
  82.     * @returns {Boolean} 点在圆形内返回true,否则返回false   
  83.     */      
  84.     GeoUtils.isPointInCircle = function (point, circle) {      
  85.         //检查类型是否正确      
  86.         if (!(point instanceof BMap.Point) ||      
  87.             !(circle instanceof BMap.Circle)) {      
  88.             return false;      
  89.         }      
  90.       
  91.         //point与圆心距离小于圆形半径,则点在圆内,否则在圆外      
  92.         var c = circle.getCenter();      
  93.         var r = circle.getRadius();      
  94.       
  95.         var dis = GeoUtils.getDistance(point, c);      
  96.         if (dis <= r) {      
  97.             return true;      
  98.         } else {      
  99.             return false;      
  100.         }      
  101.     }      
  102.       
  103.     /**   
  104.     * 判断点是否在折线上   
  105.     * @param {Point} point 点对象   
  106.     * @param {Polyline} polyline 折线对象   
  107.     * @returns {Boolean} 点在折线上返回true,否则返回false   
  108.     */      
  109.     GeoUtils.isPointOnPolyline = function (point, polyline) {      
  110.         //检查类型      
  111.         if (!(point instanceof BMap.Point) ||      
  112.              !(polyline instanceof BMap.Polyline)) {      
  113.             return false;      
  114.         }      
  115.       
  116.         //首先判断点是否在线的外包矩形内,如果在,则进一步判断,否则返回false      
  117.         var lineBounds = polyline.getBounds();      
  118.         if (!this.isPointInRect(point, lineBounds)) {      
  119.             return false;      
  120.         }      
  121.       
  122.         //判断点是否在线段上,设点为Q,线段为P1P2 ,      
  123.         //判断点Q在该线段上的依据是:( Q - P1 ) × ( P2 - P1 ) = 0,且 Q 在以 P1,P2为对角顶点的矩形内      
  124.         var pts = polyline.getPath();      
  125.         for (var i = 0; i < pts.length - 1; i++) {      
  126.             var curPt = pts[i];      
  127.             var nextPt = pts[i + 1];      
  128.             //首先判断point是否在curPt和nextPt之间,即:此判断该点是否在该线段的外包矩形内      
  129.             if (point.lng >= Math.min(curPt.lng, nextPt.lng) && point.lng <= Math.max(curPt.lng, nextPt.lng) &&      
  130.                  point.lat >= Math.min(curPt.lat, nextPt.lat) && point.lat <= Math.max(curPt.lat, nextPt.lat)) {      
  131.                 //判断点是否在直线上公式      
  132.                 var precision = (curPt.lng - point.lng) * (nextPt.lat - point.lat) - (nextPt.lng - point.lng) * (curPt.lat - point.lat);      
  133.                 if (precision < 2e-10 && precision > -2e-10) {//实质判断是否接近0      
  134.                     return true;      
  135.                 }      
  136.             }      
  137.         }      
  138.         return false;      
  139.     }      
  140.       
  141.     /**   
  142.     * 判断点是否多边形内   
  143.     * @param {Point} point 点对象   
  144.     * @param {Polyline} polygon 多边形对象   
  145.     * @returns {Boolean} 点在多边形内返回true,否则返回false   
  146.     */      
  147.     GeoUtils.isPointInPolygon = function (point, polygon) {      
  148.         //检查类型      
  149.         if (!(point instanceof BMap.Point) ||      
  150.              !(polygon instanceof BMap.Polygon)) {      
  151.             return false;      
  152.         }      
  153.       
  154.         //首先判断点是否在多边形的外包矩形内,如果在,则进一步判断,否则返回false      
  155.         var polygonBounds = polygon.getBounds();      
  156.         if (!this.isPointInRect(point, polygonBounds)) {      
  157.             return false;      
  158.         }      
  159.       
  160.         var pts = polygon.getPath(); //获取多边形点      
  161.       
  162.         //下述代码来源:http://paulbourke.net/geometry/insidepoly/,进行了部分修改      
  163.         //基本思想是利用射线法,计算射线与多边形各边的交点,如果是偶数,则点在多边形外,否则      
  164.         //在多边形内。还会考虑一些特殊情况,如点在多边形顶点上,点在多边形边上等特殊情况。      
  165.       
  166.         var N = pts.length;      
  167.         var boundOrVertex = true; //如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true      
  168.         var intersectCount = 0; //cross points count of x       
  169.         var precision = 2e-10; //浮点类型计算时候与0比较时候的容差      
  170.         var p1, p2; //neighbour bound vertices      
  171.         var p = point; //测试点      
  172.       
  173.         p1 = pts[0]; //left vertex              
  174.         for (var i = 1; i <= N; ++i) {//check all rays                  
  175.             if (p.equals(p1)) {      
  176.                 return boundOrVertex; //p is an vertex      
  177.             }      
  178.       
  179.             p2 = pts[i % N]; //right vertex                  
  180.             if (p.lat < Math.min(p1.lat, p2.lat) || p.lat > Math.max(p1.lat, p2.lat)) {//ray is outside of our interests                   
  181.                 p1 = p2;      
  182.                 continue; //next ray left point      
  183.             }      
  184.             if (p.lat > Math.min(p1.lat, p2.lat) && p.lat < Math.max(p1.lat, p2.lat)) {//ray is crossing over by the algorithm (common part of)      
  185.                 if (p.lng <= Math.max(p1.lng, p2.lng)) {//x is before of ray                          
  186.                     if (p1.lat == p2.lat && p.lng >= Math.min(p1.lng, p2.lng)) {//overlies on a horizontal ray      
  187.                         return boundOrVertex;      
  188.                     }      
  189.       
  190.                     if (p1.lng == p2.lng) {//ray is vertical               
  191.       
  192.       
  193.                         if (p1.lng == p.lng) {//overlies on a vertical ray      
  194.                             return boundOrVertex;      
  195.                         } else {//before ray      
  196.                             ++intersectCount;      
  197.                         }      
  198.                     } else {//cross point on the left side                 
  199.       
  200.       
  201.                         var xinters = (p.lat - p1.lat) * (p2.lng - p1.lng) / (p2.lat - p1.lat) + p1.lng; //cross point of lng                    
  202.       
  203.       
  204.                         if (Math.abs(p.lng - xinters) < precision) {//overlies on a ray      
  205.                             return boundOrVertex;      
  206.                         }      
  207.       
  208.                         if (p.lng < xinters) {//before ray      
  209.                             ++intersectCount;      
  210.                         }      
  211.                     }      
  212.                 }      
  213.             } else {//special case when ray is crossing through the vertex                      
  214.                 if (p.lat == p2.lat && p.lng <= p2.lng) {//p crossing over p2                          
  215.                     var p3 = pts[(i + 1) % N]; //next vertex               
  216.       
  217.       
  218.                     if (p.lat >= Math.min(p1.lat, p3.lat) && p.lat <= Math.max(p1.lat, p3.lat)) {//p.lat lies between p1.lat & p3.lat      
  219.                         ++intersectCount;      
  220.                     } else {      
  221.                         intersectCount += 2;      
  222.                     }      
  223.                 }      
  224.             }      
  225.             p1 = p2; //next ray left point      
  226.         }      
  227.       
  228.         if (intersectCount % 2 == 0) {//偶数在多边形外      
  229.             return false;      
  230.         } else { //奇数在多边形内      
  231.             return true;      
  232.         }      
  233.     }      
  234.       
  235.     /**   
  236.     * 将度转化为弧度   
  237.     * @param {degree} Number 度        
  238.     * @returns {Number} 弧度   
  239.     */      
  240.     GeoUtils.degreeToRad = function (degree) {      
  241.         return Math.PI * degree / 180;      
  242.     }      
  243.       
  244.     /**   
  245.     * 将弧度转化为度   
  246.     * @param {radian} Number 弧度        
  247.     * @returns {Number} 度   
  248.     */      
  249.     GeoUtils.radToDegree = function (rad) {      
  250.         return (180 * rad) / Math.PI;      
  251.     }      
  252.       
  253.     /**   
  254.     * 将v值限定在a,b之间,纬度使用   
  255.     */      
  256.     function _getRange(v, a, b) {      
  257.         if (a != null) {      
  258.             v = Math.max(v, a);      
  259.         }      
  260.         if (b != null) {      
  261.             v = Math.min(v, b);      
  262.         }      
  263.         return v;      
  264.     }      
  265.       
  266.     /**   
  267.     * 将v值限定在a,b之间,经度使用   
  268.     */      
  269.     function _getLoop(v, a, b) {      
  270.         while (v > b) {      
  271.             v -= b - a      
  272.         }      
  273.         while (v < a) {      
  274.             v += b - a      
  275.         }      
  276.         return v;      
  277.     }      
  278.       
  279.     /**   
  280.     * 计算两点之间的距离,两点坐标必须为经纬度   
  281.     * @param {point1} Point 点对象   
  282.     * @param {point2} Point 点对象   
  283.     * @returns {Number} 两点之间距离,单位为米   
  284.     */      
  285.     GeoUtils.getDistance = function (point1, point2) {      
  286.         //判断类型      
  287.         if (!(point1 instanceof BMap.Point) ||      
  288.              !(point2 instanceof BMap.Point)) {      
  289.             return 0;      
  290.         }      
  291.       
  292.         point1.lng = _getLoop(point1.lng, -180, 180);      
  293.         point1.lat = _getRange(point1.lat, -74, 74);      
  294.         point2.lng = _getLoop(point2.lng, -180, 180);      
  295.         point2.lat = _getRange(point2.lat, -74, 74);      
  296.       
  297.         var x1, x2, y1, y2;      
  298.         x1 = GeoUtils.degreeToRad(point1.lng);      
  299.         y1 = GeoUtils.degreeToRad(point1.lat);      
  300.         x2 = GeoUtils.degreeToRad(point2.lng);      
  301.         y2 = GeoUtils.degreeToRad(point2.lat);      
  302.       
  303.         return EARTHRADIUS * Math.acos((Math.sin(y1) * Math.sin(y2) + Math.cos(y1) * Math.cos(y2) * Math.cos(x2 - x1)));      
  304.     }      
  305.       
  306.     /**   
  307.     * 计算折线或者点数组的长度   
  308.     * @param {Polyline|Array<Point>} polyline 折线对象或者点数组   
  309.     * @returns {Number} 折线或点数组对应的长度   
  310.     */      
  311.     GeoUtils.getPolylineDistance = function (polyline) {      
  312.         //检查类型      
  313.         if (polyline instanceof BMap.Polyline ||      
  314.              polyline instanceof Array) {      
  315.             //将polyline统一为数组      
  316.             var pts;      
  317.             if (polyline instanceof BMap.Polyline) {      
  318.                 pts = polyline.getPath();      
  319.             } else {      
  320.                 pts = polyline;      
  321.             }      
  322.       
  323.             if (pts.length < 2) {//小于2个点,返回0      
  324.                 return 0;      
  325.             }      
  326.       
  327.             //遍历所有线段将其相加,计算整条线段的长度      
  328.             var totalDis = 0;      
  329.             for (var i = 0; i < pts.length - 1; i++) {      
  330.                 var curPt = pts[i];      
  331.                 var nextPt = pts[i + 1]      
  332.                 var dis = GeoUtils.getDistance(curPt, nextPt);      
  333.                 totalDis += dis;      
  334.             }      
  335.       
  336.             return totalDis;      
  337.       
  338.         } else {      
  339.             return 0;      
  340.         }      
  341.     }      
  342.       
  343.     /**   
  344.     * 计算多边形面或点数组构建图形的面积,注意:坐标类型只能是经纬   
  345.    
  346.     度,且不适合计算自相交多边形的面积   
  347.     * @param {Polygon|Array<Point>} polygon 多边形面对象或者点数   
  348.    
  349.     组   
  350.     * @returns {Number} 多边形面或点数组构成图形的面积   
  351.     */      
  352.     GeoUtils.getPolygonArea = function (polygon) {      
  353.         //检查类型      
  354.         if (!(polygon instanceof BMap.Polygon) &&      
  355.              !(polygon instanceof Array)) {      
  356.             return 0;      
  357.         }      
  358.         var pts;      
  359.         if (polygon instanceof BMap.Polygon) {      
  360.             pts = polygon.getPath();      
  361.         } else {      
  362.             pts = polygon;      
  363.         }      
  364.       
  365.         if (pts.length < 3) {//小于3个顶点,不能构建面      
  366.             return 0;      
  367.         }      
  368.       
  369.         var totalArea = 0; //初始化总面积      
  370.         var LowX = 0.0;      
  371.         var LowY = 0.0;      
  372.         var MiddleX = 0.0;      
  373.         var MiddleY = 0.0;      
  374.         var HighX = 0.0;      
  375.         var HighY = 0.0;      
  376.         var AM = 0.0;      
  377.         var BM = 0.0;      
  378.         var CM = 0.0;      
  379.         var AL = 0.0;      
  380.         var BL = 0.0;      
  381.         var CL = 0.0;      
  382.         var AH = 0.0;      
  383.         var BH = 0.0;      
  384.         var CH = 0.0;      
  385.         var CoefficientL = 0.0;      
  386.         var CoefficientH = 0.0;      
  387.         var ALtangent = 0.0;      
  388.         var BLtangent = 0.0;      
  389.         var CLtangent = 0.0;      
  390.         var AHtangent = 0.0;      
  391.         var BHtangent = 0.0;      
  392.         var CHtangent = 0.0;      
  393.         var ANormalLine = 0.0;      
  394.         var BNormalLine = 0.0;      
  395.         var CNormalLine = 0.0;      
  396.         var OrientationValue = 0.0;      
  397.         var AngleCos = 0.0;      
  398.         var Sum1 = 0.0;      
  399.         var Sum2 = 0.0;      
  400.         var Count2 = 0;      
  401.         var Count1 = 0;      
  402.         var Sum = 0.0;      
  403.         var Radius = EARTHRADIUS; //6378137.0,WGS84椭球半径       
  404.         var Count = pts.length;      
  405.         for (var i = 0; i < Count; i++) {      
  406.             if (i == 0) {      
  407.                 LowX = pts[Count - 1].lng * Math.PI / 180;      
  408.                 LowY = pts[Count - 1].lat * Math.PI / 180;      
  409.                 MiddleX = pts[0].lng * Math.PI / 180;      
  410.                 MiddleY = pts[0].lat * Math.PI / 180;      
  411.                 HighX = pts[1].lng * Math.PI / 180;      
  412.                 HighY = pts[1].lat * Math.PI / 180;      
  413.             }      
  414.             else if (i == Count - 1) {      
  415.                 LowX = pts[Count - 2].lng * Math.PI / 180;      
  416.                 LowY = pts[Count - 2].lat * Math.PI / 180;      
  417.                 MiddleX = pts[Count - 1].lng * Math.PI / 180;      
  418.                 MiddleY = pts[Count - 1].lat * Math.PI / 180;      
  419.                 HighX = pts[0].lng * Math.PI / 180;      
  420.                 HighY = pts[0].lat * Math.PI / 180;      
  421.             }      
  422.             else {      
  423.                 LowX = pts[i - 1].lng * Math.PI / 180;      
  424.                 LowY = pts[i - 1].lat * Math.PI / 180;      
  425.                 MiddleX = pts[i].lng * Math.PI / 180;      
  426.                 MiddleY = pts[i].lat * Math.PI / 180;      
  427.                 HighX = pts[i + 1].lng * Math.PI / 180;      
  428.                 HighY = pts[i + 1].lat * Math.PI / 180;      
  429.             }      
  430.             AM = Math.cos(MiddleY) * Math.cos(MiddleX);      
  431.             BM = Math.cos(MiddleY) * Math.sin(MiddleX);      
  432.             CM = Math.sin(MiddleY);      
  433.             AL = Math.cos(LowY) * Math.cos(LowX);      
  434.             BL = Math.cos(LowY) * Math.sin(LowX);      
  435.             CL = Math.sin(LowY);      
  436.             AH = Math.cos(HighY) * Math.cos(HighX);      
  437.             BH = Math.cos(HighY) * Math.sin(HighX);      
  438.             CH = Math.sin(HighY);      
  439.             CoefficientL = (AM * AM + BM * BM + CM * CM) / (AM * AL + BM * BL + CM * CL);      
  440.             CoefficientH = (AM * AM + BM * BM + CM * CM) / (AM * AH + BM * BH + CM * CH);      
  441.             ALtangent = CoefficientL * AL - AM;      
  442.             BLtangent = CoefficientL * BL - BM;      
  443.             CLtangent = CoefficientL * CL - CM;      
  444.             AHtangent = CoefficientH * AH - AM;      
  445.             BHtangent = CoefficientH * BH - BM;      
  446.             CHtangent = CoefficientH * CH - CM;      
  447.             AngleCos = (AHtangent * ALtangent + BHtangent * BLtangent + CHtangent * CLtangent) / (Math.sqrt(AHtangent * AHtangent + BHtangent * BHtangent + CHtangent * CHtangent) * Math.sqrt(ALtangent * ALtangent + BLtangent * BLtangent + CLtangent * CLtangent));      
  448.             AngleCos = Math.acos(AngleCos);      
  449.             ANormalLine = BHtangent * CLtangent - CHtangent * BLtangent;      
  450.             BNormalLine = 0 - (AHtangent * CLtangent - CHtangent * ALtangent);      
  451.             CNormalLine = AHtangent * BLtangent - BHtangent * ALtangent;      
  452.             if (AM != 0)      
  453.                 OrientationValue = ANormalLine / AM;      
  454.             else if (BM != 0)      
  455.                 OrientationValue = BNormalLine / BM;      
  456.             else      
  457.                 OrientationValue = CNormalLine / CM;      
  458.             if (OrientationValue > 0) {      
  459.                 Sum1 += AngleCos;      
  460.                 Count1++;      
  461.             }      
  462.             else {      
  463.                 Sum2 += AngleCos;      
  464.                 Count2++;      
  465.             }      
  466.         }      
  467.         var tempSum1, tempSum2;      
  468.         tempSum1 = Sum1 + (2 * Math.PI * Count2 - Sum2);      
  469.         tempSum2 = (2 * Math.PI * Count1 - Sum1) + Sum2;      
  470.         if (Sum1 > Sum2) {      
  471.             if ((tempSum1 - (Count - 2) * Math.PI) < 1)      
  472.                 Sum = tempSum1;      
  473.             else      
  474.                 Sum = tempSum2;      
  475.         }      
  476.         else {      
  477.             if ((tempSum2 - (Count - 2) * Math.PI) < 1)      
  478.                 Sum = tempSum2;      
  479.             else      
  480.                 Sum = tempSum1;      
  481.         }      
  482.         totalArea = (Sum - (Count - 2) * Math.PI) * Radius * Radius;      
  483.         return totalArea; //返回总面积      
  484.     }      
 
原文地址:https://www.cnblogs.com/yzycoder/p/6878262.html