凸包算法

 

  -------------------------------------------- 摘要 --------------------------------------------

  本文以平面上若干点为脉络,求解该若干点的凸包及过程分析。首先需对前置输入参数(平面上的若干点)作1点假设,假设

平面上的点数n>2且各点全都不在一条直线上。下文会提供2种不同的方式求解凸包,当然在最终展示的算法是必然存在优化的可

能,毕竟现有大多数的最优算法(也许是本身就不存在一个最终的最优算法)的实现不会是一蹴而就的而是一个循序渐进的过程,

不断的优化,不断地改进实现算法的思想等等,最终成型。总之写下本文的第一目的就是为了充实自己,把我的愚见与大家分享。

 

  -------------------------------------------- 分析 --------------------------------------------

  这里提供了2种方式实现凸包算法,分别简要分析2种算法实现轮廓而不会太去纠结细节上的考量。下面直接进入分析过程:

  1. 第1种算法把它命名为斜率法,大体思路过程是:首先求出平面上点集在东南西北4各方位的最值点,如图1所示红点就

是最值点,其次连接2个相邻方位最值点之间线段,就以东北2方位为标准连接线段,过滤掉该线段之下的点集(不包括线上的点),

剩下候选点集。再次以某起点为基点分别计算与各候选点连线的斜率,显然斜率最大的连线的终点必然是所求凸包包含的点即凸

包点,并且需把起点换成改凸包点,如图2所示。最后重复上述步骤直到起点为终点为止,那么对应方位的凸包点就求出了,依

次求解其它方位的凸包点。

 

 

  2.对于第2种算法把它暂且命名为试错法吧,思路如下:首先点集作X轴的排序,并选出各方位最值点。其次对某个

区域进行凸包点搜索,假设对东北方位相间的区域操作,先初始化-获取起点合规方向的点(合规表现为:水平与

垂直方向的合力作用的方向遇到的第一个点,即在排序好的点集中筛选),然后把该点放入候选凸包点集(以下称凸包点集)

中,并把起点替换为该点。再次以起点为基点选取合规的点,并判断该点与凸包点集中的最后一个点Dn的斜率和Dn与Dn下一

个点Dn-1的斜率,如果第一个斜率大于等于第二个斜率,则直接把该点放入凸包点集,否则剔除凸包点集中的Dn,然后又判断

该点与Dn-1的斜率和Dn-1与Dn-2的斜率,即重复上述过程直到合适后停下(该过程中的边界问题这里没有表述出来,但很好处理),

当然停下后,继续替换起点为该点。最后重复上述步骤,直到起点与终点重合为止。其他区域过程类似,就不在赘述。

 

  -------------------------------------------- 源码 --------------------------------------------

  1 package algorithm;
  2 
  3 import java.util.ArrayList;
  4 import java.util.HashMap;
  5 import java.util.List;
  6 import java.util.Map;
  7 
  8 /**
  9  * @author Medusa
 10  * @date 09/12/2021
 11  * @description 凸包算法
 12  */
 13 public class ConvexHullAlgorithm {
 14 
 15     /**
 16      * 通过最大斜率的方式求出凸包点
 17      */
 18     public static List<int[]> slopeMethod(int[][] dotGatherArray) {
 19         // 求出右 上 左 下各方位的边界点集
 20         List<int[]> rightBoundaryDotList = new ArrayList<>();
 21         List<int[]> topBoundaryDotList = new ArrayList<>();
 22         List<int[]> leftBoundaryDotList = new ArrayList<>();
 23         List<int[]> belowBoundaryDotList = new ArrayList<>();
 24         getBoundaryDot(dotGatherArray, rightBoundaryDotList, topBoundaryDotList, leftBoundaryDotList,
 25                 belowBoundaryDotList);
 26         // 定义凸包点集
 27         List<int[]> convexHullDotList = new ArrayList<>();
 28         for (int i = 0; i < rightBoundaryDotList.size(); i++)
 29             convexHullDotList.add(rightBoundaryDotList.get(i));
 30         // 定义局部起止点
 31         int[] startDot = rightBoundaryDotList.get(rightBoundaryDotList.size() - 1);
 32         int[] endDot = topBoundaryDotList.get(topBoundaryDotList.size() - 1);
 33         int startIndex = topBoundaryDotList.size() - 1; // 用于判断重复点的下标
 34         if (startDot[0] == endDot[0])
 35             --startIndex;
 36         else {
 37             // 获取所有(起止点除外)与起点连线斜率不大于起止点连线斜率的候选点
 38             List<int[]> candidateDot = getCandidateDot(dotGatherArray, startDot, endDot, 0);
 39             if (candidateDot.size() > 0)
 40                 getConvexHullDot(convexHullDotList, candidateDot, startDot, endDot, true);
 41         }
 42         for (int i = startIndex; i >= 0; i--)
 43             convexHullDotList.add(topBoundaryDotList.get(i));
 44         startDot = topBoundaryDotList.get(0);
 45         endDot = leftBoundaryDotList.get(leftBoundaryDotList.size() - 1);
 46         startIndex = leftBoundaryDotList.size() - 1;
 47         if (startDot[0] == endDot[0])
 48             --startIndex;
 49         else {
 50             List<int[]> candidateDot = getCandidateDot(dotGatherArray, startDot, endDot, 1);
 51             if (candidateDot.size() > 0)
 52                 getConvexHullDot(convexHullDotList, candidateDot, startDot, endDot, true);
 53         }
 54         for (int i = startIndex; i >= 0; i--)
 55             convexHullDotList.add(leftBoundaryDotList.get(i));
 56         startDot = leftBoundaryDotList.get(0);
 57         endDot = belowBoundaryDotList.get(0);
 58         startIndex = 0;
 59         if (startDot[0] == endDot[0])
 60             ++startIndex;
 61         else {
 62             List<int[]> candidateDot = getCandidateDot(dotGatherArray, startDot, endDot, 2);
 63             if (candidateDot.size() > 0)
 64                 getConvexHullDot(convexHullDotList, candidateDot, startDot, endDot, false);
 65         }
 66         for (int i = startIndex; i < belowBoundaryDotList.size(); i++)
 67             convexHullDotList.add(belowBoundaryDotList.get(i));
 68         startDot = belowBoundaryDotList.get(belowBoundaryDotList.size() - 1);
 69         endDot = rightBoundaryDotList.get(0);
 70         if (startDot[0] == endDot[0])
 71             convexHullDotList.remove(convexHullDotList.size() - 1);
 72         else {
 73             List<int[]> candidateDot = getCandidateDot(dotGatherArray, startDot, endDot, 3);
 74             if (candidateDot.size() > 0)
 75                 getConvexHullDot(convexHullDotList, candidateDot, startDot, endDot, false);
 76         }
 77         return convexHullDotList;
 78     }
 79 
 80     /**
 81      * 生成非重复的点集
 82      */
 83     private static int[][] generateDotGather(long xMax, long yMax, int quantity) {
 84         if (xMax < 0 || yMax < 0) {
 85             System.out.println("X轴或Y轴的值不能小于0");
 86             return null;
 87         }
 88         if ((xMax + 1) * (yMax + 1) < quantity) {
 89             System.out.println("xMax,yMax所确定的最大点集数不能小于生成的点集数");
 90             return null;
 91         }
 92         int[][] dotGatherArray = new int[quantity][2];
 93         Map<String, Boolean> xyValueCounterMap = new HashMap<>(quantity);
 94         ++xMax; ++yMax;
 95         for (int i = 0; i < quantity; i++) {
 96             int xValue, yValue;
 97             Boolean xyValueCounter;
 98             do {
 99                 xValue = (int) (Math.random() * xMax);
100                 yValue = (int) (Math.random() * yMax);
101                 xyValueCounter = xyValueCounterMap.get(xValue + "" + yValue);
102             } while (null != xyValueCounter);
103             xyValueCounterMap.put(xValue + "" + yValue, true);
104             dotGatherArray[i][0] = xValue;
105             dotGatherArray[i][1] = yValue;
106         }
107         return dotGatherArray;
108     }
109 
110     private static void getBoundaryDot(int[][] dotGatherArray, List<int[]> rightBoundaryDotList,
111                                        List<int[]> topBoundaryDotList, List<int[]> leftBoundaryDotList,
112                                        List<int[]> belowBoundaryDotList) {
113         int xMax = dotGatherArray[0][0], yMax = dotGatherArray[0][1], xMin = xMax, yMin = yMax;
114         for (int i = 1; i < dotGatherArray.length; i++) {
115             int x = dotGatherArray[i][0];
116             int y = dotGatherArray[i][1];
117             if (x > xMax)
118                 xMax = x;
119             else if (x < xMin)
120                 xMin = x;
121             if (y > yMax)
122                 yMax = y;
123             else if (y < yMin)
124                 yMin = y;
125         }
126         for (int i = 0; i < dotGatherArray.length; i++) {
127             int x = dotGatherArray[i][0];
128             int y = dotGatherArray[i][1];
129             if (x == xMax)
130                 rightBoundaryDotList.add(dotGatherArray[i]);
131             else if (x == xMin)
132                 leftBoundaryDotList.add(dotGatherArray[i]);
133             if (y == yMax)
134                 topBoundaryDotList.add(dotGatherArray[i]);
135             else if (y == yMin)
136                 belowBoundaryDotList.add(dotGatherArray[i]);
137         }
138         sortBoundaryDot(rightBoundaryDotList, 1);
139         sortBoundaryDot(topBoundaryDotList, 0);
140         sortBoundaryDot(leftBoundaryDotList, 1);
141         sortBoundaryDot(belowBoundaryDotList, 0);
142     }
143 
144     private static void sortBoundaryDot(List<int[]> boundaryDotList, int index) {
145         for (int i = 1; i < boundaryDotList.size(); i++) {
146             for (int j = 0; j < boundaryDotList.size() - i; j++) {
147                 if (boundaryDotList.get(j)[index] > boundaryDotList.get(j + 1)[index]) {
148                     int[] boundaryDot = boundaryDotList.get(j + 1);
149                     boundaryDotList.set(j + 1, boundaryDotList.get(j));
150                     boundaryDotList.set(j, boundaryDot);
151                 }
152             }
153         }
154     }
155 
156     private static List<int[]> getCandidateDot(int[][] dotGatherArray, int[] startDot, int[] endDot, int flag) {
157         int startX = startDot[0], startY = startDot[1];
158         int endX = endDot[0], endY = endDot[1];
159         int yChangeRate = endY - startY, xChangeRate = endX - startX;
160         List<int[]> candidateDotList = new ArrayList<>();
161         if (0 == flag) {
162             for (int i = 0; i < dotGatherArray.length; i++) {
163                 int[] dot = dotGatherArray[i];
164                 if (dot[1] > startY && dot[0] > endX &&
165                     (yChangeRate * (dot[0] - startX) >= (dot[1] - startY) * xChangeRate))
166                     candidateDotList.add(dot);
167             }
168         } else if (1 == flag) {
169             for (int i = 0; i < dotGatherArray.length; i++) {
170                 int[] dot = dotGatherArray[i];
171                 if (dot[0] < startX && dot[1] > endY &&
172                     (yChangeRate * (dot[0] - startX) >= (dot[1] - startY) * xChangeRate))
173                     candidateDotList.add(dot);
174             }
175         } else if (2 == flag) {
176             for (int i = 0; i < dotGatherArray.length; i++) {
177                 int[] dot = dotGatherArray[i];
178                 if (dot[1] < startY && dot[0] < endX &&
179                     (yChangeRate * (dot[0] - startX) >= (dot[1] - startY) * xChangeRate))
180                     candidateDotList.add(dot);
181             }
182         } else {
183             for (int i = 0; i < dotGatherArray.length; i++) {
184                 int[] dot = dotGatherArray[i];
185                 if (dot[0] > startX && dot[1] < endY &&
186                     (yChangeRate * (dot[0] - startX) >= (dot[1] - startY) * xChangeRate))
187                     candidateDotList.add(dot);
188             }
189         }
190         quickSort(candidateDotList, 0, candidateDotList.size() - 1);
191         return candidateDotList;
192     }
193 
194     private static void quickSort(List<int[]> list, int left, int right) {
195         if (left < right) {
196             int[] temp0Array = list.get(left);
197             list.set(left, list.get((left + right) >> 1));
198             list.set((left + right) >> 1, temp0Array);
199             int[] baseArray = list.get(left);
200             int i = left, j = right;
201             while (i != j) {
202                 while (list.get(j)[0] >= baseArray[0] && i < j) j--;
203                 while (list.get(i)[0] <= baseArray[0] && i < j) i++;
204                 if (i < j) {
205                     int[] temp1Array = list.get(i);
206                     list.set(i, list.get(j));
207                     list.set(j, temp1Array);
208                 }
209             }
210             list.set(left, list.get(i));
211             list.set(i, baseArray);
212             quickSort(list, left, i - 1);
213             quickSort(list, i + 1, right);
214         }
215     }
216 
217     /**
218      * 根据候选点筛选出凸包点,起点与所有候选点连线斜率的最小值即为凸包点
219      */
220     private static void getConvexHullDot(List<int[]> convexHullDotList, List<int[]> candidateDotList,
221                                          int[] startDot, int[] endDot, boolean flag) {
222         if (flag) {
223             for (int i = 0; i < candidateDotList.size() >> 1; i++) {
224                 int[] tempArray = candidateDotList.get(i);
225                 candidateDotList.set(i, candidateDotList.get(candidateDotList.size() - 1 - i));
226                 candidateDotList.set(candidateDotList.size() - 1 - i, tempArray);
227             }
228         }
229         int startX = startDot[0], startY = startDot[1];
230         int endX = endDot[0];
231         candidateDotList.add(endDot);
232         List<Integer> convexHullDotIndex = new ArrayList<>();
233         int index = 0;
234         while (startX != endX) {
235             int y1ChangeRate = candidateDotList.get(index)[1] - startY;
236             int x1ChangeRate = candidateDotList.get(index)[0] - startX;
237             convexHullDotIndex.add(index);
238             for (int i = index + 1; i < candidateDotList.size(); i++) {
239                 int y2ChangeRate = candidateDotList.get(i)[1] - startY;
240                 int x2ChangeRate = candidateDotList.get(i)[0] - startX;
241                 int value0 = y1ChangeRate * x2ChangeRate;
242                 int value1 = y2ChangeRate * x1ChangeRate;
243                 if (value0 > value1) {
244                     convexHullDotIndex.clear();
245                     convexHullDotIndex.add(i);
246                     y1ChangeRate = y2ChangeRate;
247                     x1ChangeRate = x2ChangeRate;
248                 }
249                 else if (value0 == value1)
250                     convexHullDotIndex.add(i);
251             }
252             index = convexHullDotIndex.get(convexHullDotIndex.size() - 1);
253             startX = candidateDotList.get(index)[0];
254             startY = candidateDotList.get(index)[1];
255             ++index;
256             for (int i = 0; i < convexHullDotIndex.size(); i++)
257                 convexHullDotList.add(candidateDotList.get(convexHullDotIndex.get(i)));
258             convexHullDotIndex.clear();
259         }
260         convexHullDotList.remove(convexHullDotList.size() - 1);
261     }
262 
263     /**
264      * 以x轴降序的方式寻找边界
265      */
266     public static List<int[]> searchBoundary(int[][] dotGather) {
267         quickSort(dotGather, 0, dotGather.length - 1);
268         List<int[]> rightBoundaryDotList = new ArrayList<>();
269         rightBoundaryDotList.add(dotGather[dotGather.length - 1]);
270         for (int i = dotGather.length - 2; i >= 0; i--) {
271             if (dotGather[dotGather.length - 1][0] == dotGather[i][0])
272                 rightBoundaryDotList.add(dotGather[i]);
273             else
274                 break;
275         }
276         sortBoundaryDot(rightBoundaryDotList, 1);
277         List<int[]> leftBoundaryDotList = new ArrayList<>();
278         leftBoundaryDotList.add(dotGather[0]);
279         for (int i = 1; i < dotGather.length; i++) {
280             if (dotGather[0][0] == dotGather[i][0])
281                 leftBoundaryDotList.add(dotGather[i]);
282             else
283                 break;
284         }
285         sortBoundaryDot(leftBoundaryDotList, 1);
286         List<int[]> topBoundaryDotList = new ArrayList<>();
287         List<int[]> belowBoundaryDotList = new ArrayList<>();
288         int maxY = dotGather[0][1], minY = maxY;
289         for (int i = 1; i < dotGather.length; i++) {
290             if (maxY < dotGather[i][1])
291                 maxY = dotGather[i][1];
292             else if (minY > dotGather[i][1])
293                 minY = dotGather[i][1];
294         }
295         for (int i = 0; i < dotGather.length; i++) {
296             if (maxY == dotGather[i][1])
297                 topBoundaryDotList.add(dotGather[i]);
298             else if (minY == dotGather[i][1])
299                 belowBoundaryDotList.add(dotGather[i]);
300         }
301         sortBoundaryDot(topBoundaryDotList, 0);
302         sortBoundaryDot(belowBoundaryDotList, 0);
303         List<int[]> convexHullDotList = new ArrayList<>();
304         for (int i = 0; i < rightBoundaryDotList.size(); i++)
305             convexHullDotList.add(rightBoundaryDotList.get(i));
306         int[] startDot = rightBoundaryDotList.get(rightBoundaryDotList.size() - 1);
307         int[] endDot = topBoundaryDotList.get(topBoundaryDotList.size() - 1);
308         int startIndex = topBoundaryDotList.size() - 1;
309         if (startDot[0] == endDot[0])
310             --startIndex;
311         else
312             search(dotGather, convexHullDotList, startDot, endDot, 0);
313         for (int i = startIndex; i >= 0; i--)
314             convexHullDotList.add(topBoundaryDotList.get(i));
315         startDot = leftBoundaryDotList.get(leftBoundaryDotList.size() - 1);
316         endDot = topBoundaryDotList.get(0);
317         startIndex = leftBoundaryDotList.size() - 1;
318         if (startDot[0] == endDot[0])
319             --startIndex;
320         else
321             search(dotGather, convexHullDotList, startDot, endDot, 1);
322         for (int i = startIndex; i >= 0; i--)
323             convexHullDotList.add(leftBoundaryDotList.get(i));
324         startDot = leftBoundaryDotList.get(0);
325         endDot = belowBoundaryDotList.get(0);
326         startIndex = 0;
327         if (startDot[0] == endDot[0])
328             ++startIndex;
329         else
330             search(dotGather, convexHullDotList, startDot, endDot, 2);
331         for (int i = startIndex; i < belowBoundaryDotList.size(); i++)
332             convexHullDotList.add(belowBoundaryDotList.get(i));
333         startDot = rightBoundaryDotList.get(0);
334         endDot = belowBoundaryDotList.get(belowBoundaryDotList.size() - 1);
335         if (startDot[0] == endDot[0])
336             convexHullDotList.remove(convexHullDotList.size() - 1);
337         else
338             search(dotGather, convexHullDotList, startDot, endDot, 3);
339         return convexHullDotList;
340     }
341 
342     private static void quickSort(int[][] array, int left, int right) {
343         if (left < right) {
344             int[] temp0Array = array[left];
345             array[left] = array[(left + right) >> 1];
346             array[(left + right) >> 1] = temp0Array;
347             int[] baseArray = array[left];
348             int i = left, j = right;
349             while (i != j) {
350                 while (array[j][0] >= baseArray[0] && i < j) j--;
351                 while (array[i][0] <= baseArray[0] && i < j) i++;
352                 if (i < j) {
353                     int[] temp1Array = array[i];
354                     array[i] = array[j];
355                     array[j] = temp1Array;
356                 }
357             }
358             array[left] = array[i];
359             array[i] = baseArray;
360             quickSort(array, left, i - 1);
361             quickSort(array, i + 1, right);
362         }
363     }
364 
365     private static void search(int[][] dotGather, List<int[]> convexHullDotList, int[] startDot,
366                                int[] endDot, int flag) {
367         int startX = startDot[0], startY = startDot[1];
368         int endX = endDot[0], endY = endDot[1];
369         if (flag == 0) {
370             // 1.dot[1] - nowConvexHullDot[1] / dot[0] - nowConvexHullDot[0]
371             // <
372             // nowConvexHullDot[1] - nextConvexHullDot[1] / nowConvexHullDot[0] - nextConvexHullDot[0]
373             // yt - y1/0 < y1 - y2/x1 - x2
374             int pointer = convexHullDotList.size() - 1, limit = pointer, index = dotGather.length - 1;
375             do {
376                 int[] dot = dotGather[index--];
377                 if (dot[1] > startY && dot[0] >= endX && dot[1] <= endY) {
378                     for (int i = pointer; i > limit; i--) {
379                         int[] nowConvexHullDot = convexHullDotList.get(i);
380                         int[] nextConvexHullDot = convexHullDotList.get(i - 1);
381                         if ((dot[1] - nowConvexHullDot[1]) * (nowConvexHullDot[0] - nextConvexHullDot[0]) <
382                             (nowConvexHullDot[1] - nextConvexHullDot[1]) * (dot[0] - nowConvexHullDot[0]))
383                             convexHullDotList.remove(i);
384                         else
385                             break;
386                     }
387                     convexHullDotList.add(dot);
388                     pointer = convexHullDotList.size() - 1;
389                     startX = dot[0];
390                     startY = dot[1];
391                 }
392             } while (startX != endX && startY != endY);
393             convexHullDotList.remove(convexHullDotList.size() - 1);
394         } else if (flag == 1) {
395             // 2.dot[1] - nowConvexHullDot[1] / dot[0] - nowConvexHullDot[0]
396             // >
397             // nowConvexHullDot[1] - nextConvexHullDot[1] / nowConvexHullDot[0] - nextConvexHullDot[0]
398             // yt - y1/0 > y1 - y2/x1 - x2
399             List<int[]> tempList = new ArrayList<>();
400             tempList.add(startDot);
401             int pointer = 0, index = 0;
402             do {
403                 int[] dot = dotGather[index++];
404                 if (dot[1] > startY && dot[0] <= endX && dot[1] <= endY) {
405                     for (int i = pointer; i > 0; i--) {
406                         int[] nowConvexHullDot = tempList.get(i);
407                         int[] nextConvexHullDot = tempList.get(i - 1);
408                         if ((dot[1] - nowConvexHullDot[1]) * (nowConvexHullDot[0] - nextConvexHullDot[0]) >
409                             (nowConvexHullDot[1] - nextConvexHullDot[1]) * (dot[0] - nowConvexHullDot[0]))
410                             tempList.remove(i);
411                         else
412                             break;
413                     }
414                     tempList.add(dot);
415                     pointer = tempList.size() - 1;
416                     startX = dot[0];
417                     startY = dot[1];
418                 }
419             } while (startX != endX && startY != endY);
420             for (int i = tempList.size() - 2; i > 0; i--)
421                 convexHullDotList.add(tempList.get(i));
422         } else if (flag == 2) {
423             // 3.dot[1] - nowConvexHullDot[1] / dot[0] - nowConvexHullDot[0]
424             // <
425             // nowConvexHullDot[1] - nextConvexHullDot[1] / nowConvexHullDot[0] - nextConvexHullDot[0]
426             // yt - y1/0 < y1 - y2/x1 - x2
427             int pointer = convexHullDotList.size() - 1, limit = pointer, index = 0;
428             do {
429                 int[] dot = dotGather[index++];
430                 if (dot[1] < startY && dot[0] <= endX && dot[1] >= endY) {
431                     for (int i = pointer; i > limit; i--) {
432                         int[] nowConvexHullDot = convexHullDotList.get(i);
433                         int[] nextConvexHullDot = convexHullDotList.get(i - 1);
434                         if ((dot[1] - nowConvexHullDot[1]) * (nowConvexHullDot[0] - nextConvexHullDot[0]) <
435                             (nowConvexHullDot[1] - nextConvexHullDot[1]) * (dot[0] - nowConvexHullDot[0]))
436                             convexHullDotList.remove(i);
437                         else
438                             break;
439                     }
440                     convexHullDotList.add(dot);
441                     pointer = convexHullDotList.size() - 1;
442                     startX = dot[0];
443                     startY = dot[1];
444                 }
445             } while (startX != endX && startY != endY);
446             convexHullDotList.remove(convexHullDotList.size() - 1);
447         } else {
448             // 4.dot[1] - nowConvexHullDot[1] / dot[0] - nowConvexHullDot[0]
449             // >
450             // nowConvexHullDot[1] - nextConvexHullDot[1] / nowConvexHullDot[0] - nextConvexHullDot[0]
451             // yt - y1/0 > y1 - y2/x1 - x2
452             List<int[]> tempList = new ArrayList<>();
453             tempList.add(startDot);
454             int pointer = 0, index = dotGather.length - 1;;
455             do {
456                 int[] dot = dotGather[index--];
457                 if (dot[1] < startY && dot[0] >= endX && dot[1] >= endY) {
458                     for (int i = pointer; i > 0; i--) {
459                         int[] nowConvexHullDot = tempList.get(i);
460                         int[] nextConvexHullDot = tempList.get(i - 1);
461                         if ((dot[1] - nowConvexHullDot[1]) * (nowConvexHullDot[0] - nextConvexHullDot[0]) >
462                             (nowConvexHullDot[1] - nextConvexHullDot[1]) * (dot[0] - nowConvexHullDot[0]))
463                             tempList.remove(i);
464                         else
465                             break;
466                     }
467                     tempList.add(dot);
468                     pointer = tempList.size() - 1;
469                     startX = dot[0];
470                     startY = dot[1];
471                 }
472             } while (startX != endX && startY != endY);
473             for (int i = tempList.size() - 2; i > 0; i--)
474                 convexHullDotList.add(tempList.get(i));
475         }
476     }
477 }
View Code

 

posted @ 2022-06-10 17:10  接近风的地方  阅读(267)  评论(0编辑  收藏  举报