|
2 | 2 | // for details. All rights reserved. Use of this source code is governed by a |
3 | 3 | // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
|
| 5 | +import 'dart:math'; |
| 6 | + |
5 | 7 | import 'package:_pub_shared/data/download_counts_data.dart'; |
6 | 8 |
|
7 | 9 | Iterable<String> prepareRanges(List<VersionRangeCount> rangeDownloads) { |
@@ -79,3 +81,47 @@ Iterable<String> prepareRanges(List<VersionRangeCount> rangeDownloads) { |
79 | 81 | ); |
80 | 82 | return (closestPoint.$1, closestPoint.$2); |
81 | 83 | } |
| 84 | + |
| 85 | +/// Calculates the Euclidean distance between two points. |
| 86 | +double distance((num, num) point, (double, double) point2) { |
| 87 | + final dx = point.$1 - point2.$1; |
| 88 | + final dy = point.$2 - point2.$2; |
| 89 | + return sqrt(dx * dx + dy * dy); |
| 90 | +} |
| 91 | + |
| 92 | +/// Finds the closest point on [path] (a series of points defining the line |
| 93 | +/// segments) to a given [point]. |
| 94 | +(num, num) closestPointOnPath( |
| 95 | + List<(double, double)> path, (double, double) point) { |
| 96 | + if (path.length < 2) { |
| 97 | + return (double.maxFinite, double.maxFinite); |
| 98 | + } |
| 99 | + (num, num) closestPoint = (double.maxFinite, double.maxFinite); |
| 100 | + var minDistance = double.infinity; |
| 101 | + for (int i = 0; i < path.length - 1; i++) { |
| 102 | + final p = closestPointOnLine(path[i], path[i + 1], point); |
| 103 | + final dist = distance(p, point); |
| 104 | + if (dist < minDistance) { |
| 105 | + minDistance = dist; |
| 106 | + closestPoint = p; |
| 107 | + } |
| 108 | + } |
| 109 | + return closestPoint; |
| 110 | +} |
| 111 | + |
| 112 | +/// Determines if a given [point] is within a specified [tolerance] distance of |
| 113 | +/// a [path] defined by a series of points. |
| 114 | +bool isPointOnPathWithTolerance( |
| 115 | + List<(double, double)> path, (double, double) point, double tolerance) { |
| 116 | + if (path.length < 2) { |
| 117 | + // Not enough points to define a line segment. |
| 118 | + return false; |
| 119 | + } |
| 120 | + |
| 121 | + final closestPoint = closestPointOnPath(path, point); |
| 122 | + final dist = distance(closestPoint, point); |
| 123 | + if (dist < tolerance) { |
| 124 | + return true; |
| 125 | + } |
| 126 | + return false; |
| 127 | +} |
0 commit comments