(points)
| 26 | } |
| 27 | |
| 28 | function convexHull(points) { |
| 29 | const pointsLen = points.length |
| 30 | if (pointsLen <= 2) { |
| 31 | throw new Error('Minimum of 3 points is required to form closed polygon!') |
| 32 | } |
| 33 | |
| 34 | points.sort(compare) |
| 35 | const p1 = points[0] |
| 36 | const p2 = points[pointsLen - 1] |
| 37 | |
| 38 | // Divide Hull in two halves |
| 39 | const upperPoints = [] |
| 40 | const lowerPoints = [] |
| 41 | |
| 42 | upperPoints.push(p1) |
| 43 | lowerPoints.push(p1) |
| 44 | |
| 45 | for (let i = 1; i < pointsLen; i++) { |
| 46 | if (i === pointsLen - 1 || orientation(p1, points[i], p2) !== -1) { |
| 47 | let upLen = upperPoints.length |
| 48 | |
| 49 | while ( |
| 50 | upLen >= 2 && |
| 51 | orientation( |
| 52 | upperPoints[upLen - 2], |
| 53 | upperPoints[upLen - 1], |
| 54 | points[i] |
| 55 | ) === -1 |
| 56 | ) { |
| 57 | upperPoints.pop() |
| 58 | upLen = upperPoints.length |
| 59 | } |
| 60 | upperPoints.push(points[i]) |
| 61 | } |
| 62 | if (i === pointsLen - 1 || orientation(p1, points[i], p2) !== 1) { |
| 63 | let lowLen = lowerPoints.length |
| 64 | while ( |
| 65 | lowLen >= 2 && |
| 66 | orientation( |
| 67 | lowerPoints[lowLen - 2], |
| 68 | lowerPoints[lowLen - 1], |
| 69 | points[i] |
| 70 | ) === 1 |
| 71 | ) { |
| 72 | lowerPoints.pop() |
| 73 | lowLen = lowerPoints.length |
| 74 | } |
| 75 | lowerPoints.push(points[i]) |
| 76 | } |
| 77 | } |
| 78 | const hull = [] |
| 79 | for (let i = 1; i < upperPoints.length - 1; i++) { |
| 80 | hull.push(upperPoints[i]) |
| 81 | } |
| 82 | for (let i = lowerPoints.length - 1; i >= 0; i--) { |
| 83 | hull.push(lowerPoints[i]) |
| 84 | } |
| 85 |
no test coverage detected