{
  "version": 3,
  "sources": ["../../../../src/lib/primitives/geometry/Circle2d.ts"],
  "sourcesContent": ["import { Box } from '../Box'\nimport { intersectLineSegmentCircle } from '../intersect'\nimport { PI2, getPointOnCircle } from '../utils'\nimport { Vec, VecLike } from '../Vec'\nimport { getVerticesCountForArcLength } from './geometry-constants'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\n\n/** @public */\nexport class Circle2d extends Geometry2d {\n\tprivate _center: Vec\n\tprivate _radius: number\n\tprivate _x: number\n\tprivate _y: number\n\n\tconstructor(\n\t\tpublic config: Omit<Geometry2dOptions, 'isClosed'> & {\n\t\t\tx?: number\n\t\t\ty?: number\n\t\t\tradius: number\n\t\t\tisFilled: boolean\n\t\t}\n\t) {\n\t\tsuper({ isClosed: true, ...config })\n\t\tconst { x = 0, y = 0, radius } = config\n\t\tthis._x = x\n\t\tthis._y = y\n\t\tthis._center = new Vec(radius + x, radius + y)\n\t\tthis._radius = radius\n\t}\n\n\tgetBounds() {\n\t\treturn new Box(this._x, this._y, this._radius * 2, this._radius * 2)\n\t}\n\n\tgetVertices(): Vec[] {\n\t\tconst { _center, _radius: radius } = this\n\t\tconst perimeter = PI2 * radius\n\t\tconst vertices: Vec[] = []\n\t\tfor (let i = 0, n = getVerticesCountForArcLength(perimeter); i < n; i++) {\n\t\t\tconst angle = (i / n) * PI2\n\t\t\tvertices.push(getPointOnCircle(_center, radius, angle))\n\t\t}\n\t\treturn vertices\n\t}\n\n\tnearestPoint(point: VecLike): Vec {\n\t\t// Inlined: Vec.Sub(point, _center).uni().mul(radius).add(_center)\n\t\t// Computes direction from center to point, normalizes, scales by radius, offsets by center.\n\t\tconst { _center, _radius: radius } = this\n\t\tconst dx = point.x - _center.x\n\t\tconst dy = point.y - _center.y\n\t\tconst len = Math.sqrt(dx * dx + dy * dy)\n\t\tif (len === 0) return new Vec(_center.x + radius, _center.y)\n\t\tconst scale = radius / len\n\t\treturn new Vec(_center.x + dx * scale, _center.y + dy * scale)\n\t}\n\n\toverride distanceToPoint(point: VecLike, hitInside = false): number {\n\t\t// Inlined: Math.abs(Vec.Dist(point, _center) - radius)\n\t\t// Computes distance from point to center, then subtracts radius for edge distance.\n\t\t// Returns negative when inside a filled circle to indicate containment.\n\t\tconst { _center, _radius: radius } = this\n\t\tconst dx = point.x - _center.x\n\t\tconst dy = point.y - _center.y\n\t\tconst dist = Math.sqrt(dx * dx + dy * dy)\n\t\tconst distToEdge = dist - radius\n\t\tif (distToEdge < 0 && (this.isFilled || hitInside)) {\n\t\t\treturn distToEdge\n\t\t}\n\t\treturn Math.abs(distToEdge)\n\t}\n\n\toverride hitTestPoint(point: VecLike, margin = 0, hitInside = false): boolean {\n\t\t// Equivalent to: dist = Vec.Dist(point, _center); return dist within [radius - margin, radius + margin]\n\t\t// Uses squared distances throughout to avoid any sqrt calls.\n\t\tconst { _center, _radius: radius } = this\n\t\tconst dx = point.x - _center.x\n\t\tconst dy = point.y - _center.y\n\t\tconst dist2 = dx * dx + dy * dy\n\t\tif ((this.isFilled || hitInside) && dist2 <= radius * radius) {\n\t\t\treturn true\n\t\t}\n\t\tconst outerR = radius + margin\n\t\tif (dist2 > outerR * outerR) return false\n\t\tconst innerR = radius - margin\n\t\tif (innerR <= 0) return true\n\t\treturn dist2 >= innerR * innerR\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike, distance = 0): boolean {\n\t\tconst { _center, _radius: radius } = this\n\t\treturn intersectLineSegmentCircle(A, B, _center, radius + distance) !== null\n\t}\n\n\tgetSvgPathData(): string {\n\t\tconst { _center, _radius: radius } = this\n\t\treturn `M${_center.x + radius},${_center.y} a${radius},${radius} 0 1,0 ${radius * 2},0a${radius},${radius} 0 1,0 -${radius * 2},0`\n\t}\n}\n"],
  "mappings": "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",
  "names": []
}
