(
cx: number, cy: number, r: number, startAngle: number, endAngle: number, anticlockwise: boolean,
x: number, y: number, out: number[]
)
| 84 | |
| 85 | |
| 86 | function projectPointToArc( |
| 87 | cx: number, cy: number, r: number, startAngle: number, endAngle: number, anticlockwise: boolean, |
| 88 | x: number, y: number, out: number[] |
| 89 | ): number { |
| 90 | x -= cx; |
| 91 | y -= cy; |
| 92 | const d = Math.sqrt(x * x + y * y); |
| 93 | x /= d; |
| 94 | y /= d; |
| 95 | |
| 96 | // Intersect point. |
| 97 | const ox = x * r + cx; |
| 98 | const oy = y * r + cy; |
| 99 | |
| 100 | if (Math.abs(startAngle - endAngle) % PI2 < 1e-4) { |
| 101 | // Is a circle |
| 102 | out[0] = ox; |
| 103 | out[1] = oy; |
| 104 | return d - r; |
| 105 | } |
| 106 | |
| 107 | if (anticlockwise) { |
| 108 | const tmp = startAngle; |
| 109 | startAngle = normalizeRadian(endAngle); |
| 110 | endAngle = normalizeRadian(tmp); |
| 111 | } |
| 112 | else { |
| 113 | startAngle = normalizeRadian(startAngle); |
| 114 | endAngle = normalizeRadian(endAngle); |
| 115 | } |
| 116 | if (startAngle > endAngle) { |
| 117 | endAngle += PI2; |
| 118 | } |
| 119 | |
| 120 | let angle = Math.atan2(y, x); |
| 121 | if (angle < 0) { |
| 122 | angle += PI2; |
| 123 | } |
| 124 | if ((angle >= startAngle && angle <= endAngle) |
| 125 | || (angle + PI2 >= startAngle && angle + PI2 <= endAngle)) { |
| 126 | // Project point is on the arc. |
| 127 | out[0] = ox; |
| 128 | out[1] = oy; |
| 129 | return d - r; |
| 130 | } |
| 131 | |
| 132 | const x1 = r * Math.cos(startAngle) + cx; |
| 133 | const y1 = r * Math.sin(startAngle) + cy; |
| 134 | |
| 135 | const x2 = r * Math.cos(endAngle) + cx; |
| 136 | const y2 = r * Math.sin(endAngle) + cy; |
| 137 | |
| 138 | const d1 = (x1 - x) * (x1 - x) + (y1 - y) * (y1 - y); |
| 139 | const d2 = (x2 - x) * (x2 - x) + (y2 - y) * (y2 - y); |
| 140 | |
| 141 | if (d1 < d2) { |
| 142 | out[0] = x1; |
| 143 | out[1] = y1; |
no outgoing calls
no test coverage detected
searching dependent graphs…