Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | 11x 11x 11x 11x 67x 5x 1x 1x 6x 1x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 4x 5x 3x 5x 6x 3x 3x 3x 3x 81x 81x 3x 3x 3x 3x 5x 5x 5x 5x 5x 271x 271x 5x 5x 276x 276x 276x 276x 276x | import {DPoint, EARTH_RADIUS_IN_METERS} from './DPoint'; import {DPolygon} from './DPolygon'; import {checkFunction} from './utils'; // eslint-disable-next-line padded-blocks export class DCircle { /** * @param [center=(0,0)] * @param [r=0] */ constructor(public center: DPoint = DPoint.zero(), public r: number = 0) {} toString(): string { return `(${this.center.toString()}, ${this.r})`; } getValue(): {center: DPoint, r: number} { return {center: this.center, r: this.r}; } clone(): DCircle { return new DCircle(this.center, this.r); } /** * Find intersection points with other circle. * *  * @param c */ findPoints(c: DCircle): DPoint[] | number { if (this.equal(c)) { return Infinity; } const { center: {x: x0, y: y0}, r: r0 } = this; const { center: {x: x1, y: y1}, r: r1 } = c; const r02 = r0 * r0; const d = this.center.distance(c.center); const a = (r02 - r1 * r1 + d * d) / (2 * d); const h = Math.sqrt(r02 - a * a); const ad = a / d; const dy = y1 - y0; const dx = x1 - x0; const hd = h / d; const x2 = x0 + ad * (x1 - x0); const y2 = y0 + ad * (y1 - y0); const x31 = x2 + hd * dy; const y31 = y2 - hd * dx; const x32 = x2 - hd * dy; const y32 = y2 + hd * dx; const res = []; if (!isNaN(x31) && !isNaN(y31)) { res.push(new DPoint(x31, y31)); } if (!isNaN(x32) && !isNaN(y32) && !(x31 === x32 && y31 === y32)) { res.push(new DPoint(x32, y32)); } return res; } equal({center, r}: DCircle): boolean { return this.center.equal(center) && this.r === r; } /** * Transform circle to polygon * *  * @param [pointCount=64] * @param [startAngle=0] * @param [stopAngle=2*Math.PI] */ findPolygonInside(pointCount: number = 64, startAngle: number = 0, stopAngle: number = 2 * Math.PI): DPolygon { const step = 2 * Math.PI / pointCount; const points: DPoint[] = []; let angle = startAngle; while (angle < stopAngle - step) { points.push(new DPoint(this.r).scale(Math.cos(angle), Math.sin(angle)) .move(this.center)); angle += step; } const x = this.r * Math.cos(stopAngle) + this.center.x; const y = this.r * Math.sin(stopAngle) + this.center.y; points.push(new DPoint(x, y)); return new DPolygon(points); } /** * Transform circle to polygon on sphere. It would be different for different latitude. * * @remarks * Center should be Lng/Lat. * * @remarks * Radius should be in meters. * *  * @param [pointCount=64] * @param [startAngle=0] * @param [stopAngle=2*Math.PI] */ findPolygonInsideOnSphere( pointCount: number = 64, startAngle: number = 0, stopAngle: number = 2 * Math.PI ): DPolygon { checkFunction('findPolygonInsideOnSphere') .checkArgument('center') .shouldBeDegree(this.center); const step = 2 * Math.PI / pointCount; const points: DPoint[] = []; let angle = startAngle; while (angle < stopAngle - step) { points.push(this.sphereOffset(angle)); angle += step; } points.push(this.sphereOffset(stopAngle)); return new DPolygon(points); } private sphereOffset(bearing: number, earthRadius = EARTH_RADIUS_IN_METERS): DPoint { const {x: lon1, y: lat1} = this.center.clone().degreeToRadians(); const dByR = this.r / earthRadius; const lat = Math.asin(Math.sin(lat1) * Math.cos(dByR) + Math.cos(lat1) * Math.sin(dByR) * Math.cos(bearing)); const lon = lon1 + Math.atan2( Math.sin(bearing) * Math.sin(dByR) * Math.cos(lat1), Math.cos(dByR) - Math.sin(lat1) * Math.sin(lat) ); return new DPoint(lon, lat).radiansToDegrees(); } } |