{"version":3,"file":"Ellipse.mjs","sources":["../../../src/maths/shapes/Ellipse.ts"],"sourcesContent":["import { Rectangle } from './Rectangle';\n\nimport type { ShapePrimitive } from './ShapePrimitive';\n\n/**\n * The Ellipse object is used to help draw graphics and can also be used to specify a hit area for containers.\n * @example\n * ```ts\n * // Basic ellipse creation\n * const ellipse = new Ellipse(100, 100, 20, 10);\n *\n * // Use as a hit area\n * container.hitArea = new Ellipse(0, 0, 50, 25);\n *\n * // Check point containment\n * const isInside = ellipse.contains(mouseX, mouseY);\n *\n * // Get bounding box\n * const bounds = ellipse.getBounds();\n * ```\n * @remarks\n * - Defined by center (x,y) and half dimensions\n * - Total width = halfWidth * 2\n * - Total height = halfHeight * 2\n * @see {@link Rectangle} For rectangular shapes\n * @see {@link Circle} For circular shapes\n * @category maths\n * @standard\n */\nexport class Ellipse implements ShapePrimitive\n{\n    /**\n     * The X coordinate of the center of this ellipse\n     * @example\n     * ```ts\n     * // Basic x position\n     * const ellipse = new Ellipse();\n     * ellipse.x = 100;\n     * ```\n     * @default 0\n     */\n    public x: number;\n\n    /**\n     * The Y coordinate of the center of this ellipse\n     * @example\n     * ```ts\n     * // Basic y position\n     * const ellipse = new Ellipse();\n     * ellipse.y = 200;\n     * ```\n     * @default 0\n     */\n    public y: number;\n\n    /**\n     * The half width of this ellipse\n     * @example\n     * ```ts\n     * // Set half width\n     * const ellipse = new Ellipse(100, 100);\n     * ellipse.halfWidth = 50; // Total width will be 100\n     * ```\n     * @default 0\n     */\n    public halfWidth: number;\n\n    /**\n     * The half height of this ellipse\n     * @example\n     * ```ts\n     * // Set half height\n     * const ellipse = new Ellipse(100, 100);\n     * ellipse.halfHeight = 25; // Total height will be 50\n     * ```\n     * @default 0\n     */\n    public halfHeight: number;\n\n    /**\n     * The type of the object, mainly used to avoid `instanceof` checks\n     * @example\n     * ```ts\n     * // Check shape type\n     * const shape = new Ellipse(0, 0, 50, 25);\n     * console.log(shape.type); // 'ellipse'\n     *\n     * // Use in type guards\n     * if (shape.type === 'ellipse') {\n     *     console.log(shape.halfWidth, shape.halfHeight);\n     * }\n     * ```\n     * @readonly\n     * @default 'ellipse'\n     * @see {@link SHAPE_PRIMITIVE} For all shape types\n     */\n    public readonly type = 'ellipse';\n\n    /**\n     * @param x - The X coordinate of the center of this ellipse\n     * @param y - The Y coordinate of the center of this ellipse\n     * @param halfWidth - The half width of this ellipse\n     * @param halfHeight - The half height of this ellipse\n     */\n    constructor(x = 0, y = 0, halfWidth = 0, halfHeight = 0)\n    {\n        this.x = x;\n        this.y = y;\n        this.halfWidth = halfWidth;\n        this.halfHeight = halfHeight;\n    }\n\n    /**\n     * Creates a clone of this Ellipse instance.\n     * @example\n     * ```ts\n     * // Basic cloning\n     * const original = new Ellipse(100, 100, 50, 25);\n     * const copy = original.clone();\n     *\n     * // Clone and modify\n     * const modified = original.clone();\n     * modified.halfWidth *= 2;\n     * modified.halfHeight *= 2;\n     *\n     * // Verify independence\n     * console.log(original.halfWidth);  // 50\n     * console.log(modified.halfWidth);  // 100\n     * ```\n     * @returns A copy of the ellipse\n     * @see {@link Ellipse.copyFrom} For copying into existing ellipse\n     * @see {@link Ellipse.copyTo} For copying to another ellipse\n     */\n    public clone(): Ellipse\n    {\n        return new Ellipse(this.x, this.y, this.halfWidth, this.halfHeight);\n    }\n\n    /**\n     * Checks whether the x and y coordinates given are contained within this ellipse.\n     * Uses normalized coordinates and the ellipse equation to determine containment.\n     * @example\n     * ```ts\n     * // Basic containment check\n     * const ellipse = new Ellipse(100, 100, 50, 25);\n     * const isInside = ellipse.contains(120, 110);\n     * ```\n     * @remarks\n     * - Uses ellipse equation (x²/a² + y²/b² ≤ 1)\n     * - Returns false if dimensions are 0 or negative\n     * - Normalized to center (0,0) for calculation\n     * @param x - The X coordinate of the point to test\n     * @param y - The Y coordinate of the point to test\n     * @returns Whether the x/y coords are within this ellipse\n     * @see {@link Ellipse.strokeContains} For checking stroke intersection\n     * @see {@link Ellipse.getBounds} For getting containing rectangle\n     */\n    public contains(x: number, y: number): boolean\n    {\n        if (this.halfWidth <= 0 || this.halfHeight <= 0)\n        {\n            return false;\n        }\n\n        // normalize the coords to an ellipse with center 0,0\n        let normx = ((x - this.x) / this.halfWidth);\n        let normy = ((y - this.y) / this.halfHeight);\n\n        normx *= normx;\n        normy *= normy;\n\n        return (normx + normy <= 1);\n    }\n\n    /**\n     * Checks whether the x and y coordinates given are contained within this ellipse including stroke.\n     * @example\n     * ```ts\n     * // Basic stroke check\n     * const ellipse = new Ellipse(100, 100, 50, 25);\n     * const isOnStroke = ellipse.strokeContains(150, 100, 4); // 4px line width\n     *\n     * // Check with different alignments\n     * const innerStroke = ellipse.strokeContains(150, 100, 4, 1);   // Inside\n     * const centerStroke = ellipse.strokeContains(150, 100, 4, 0.5); // Centered\n     * const outerStroke = ellipse.strokeContains(150, 100, 4, 0);   // Outside\n     * ```\n     * @remarks\n     * - Uses normalized ellipse equations\n     * - Considers stroke alignment\n     * - Returns false if dimensions are 0\n     * @param x - The X coordinate of the point to test\n     * @param y - The Y coordinate of the point to test\n     * @param strokeWidth - The width of the line to check\n     * @param alignment - The alignment of the stroke (1 = inner, 0.5 = centered, 0 = outer)\n     * @returns Whether the x/y coords are within this ellipse's stroke\n     * @see {@link Ellipse.contains} For checking fill containment\n     * @see {@link Ellipse.getBounds} For getting stroke bounds\n     */\n    public strokeContains(x: number, y: number, strokeWidth: number, alignment: number = 0.5): boolean\n    {\n        const { halfWidth, halfHeight } = this;\n\n        if (halfWidth <= 0 || halfHeight <= 0)\n        {\n            return false;\n        }\n\n        const strokeOuterWidth = strokeWidth * (1 - alignment);\n        const strokeInnerWidth = strokeWidth - strokeOuterWidth;\n\n        const innerHorizontal = halfWidth - strokeInnerWidth;\n        const innerVertical = halfHeight - strokeInnerWidth;\n\n        const outerHorizontal = halfWidth + strokeOuterWidth;\n        const outerVertical = halfHeight + strokeOuterWidth;\n\n        const normalizedX = x - this.x;\n        const normalizedY = y - this.y;\n\n        const innerEllipse = ((normalizedX * normalizedX) / (innerHorizontal * innerHorizontal))\n            + ((normalizedY * normalizedY) / (innerVertical * innerVertical));\n\n        const outerEllipse = ((normalizedX * normalizedX) / (outerHorizontal * outerHorizontal))\n            + ((normalizedY * normalizedY) / (outerVertical * outerVertical));\n\n        return innerEllipse > 1 && outerEllipse <= 1;\n    }\n\n    /**\n     * Returns the framing rectangle of the ellipse as a Rectangle object.\n     * @example\n     * ```ts\n     * // Basic bounds calculation\n     * const ellipse = new Ellipse(100, 100, 50, 25);\n     * const bounds = ellipse.getBounds();\n     * // bounds: x=50, y=75, width=100, height=50\n     *\n     * // Reuse existing rectangle\n     * const rect = new Rectangle();\n     * ellipse.getBounds(rect);\n     * ```\n     * @remarks\n     * - Creates Rectangle if none provided\n     * - Top-left is (x-halfWidth, y-halfHeight)\n     * - Width is halfWidth * 2\n     * - Height is halfHeight * 2\n     * @param out - Optional Rectangle object to store the result\n     * @returns The framing rectangle\n     * @see {@link Rectangle} For rectangle properties\n     * @see {@link Ellipse.contains} For checking if a point is inside\n     */\n    public getBounds(out?: Rectangle): Rectangle\n    {\n        out ||= new Rectangle();\n\n        out.x = this.x - this.halfWidth;\n        out.y = this.y - this.halfHeight;\n        out.width = this.halfWidth * 2;\n        out.height = this.halfHeight * 2;\n\n        return out;\n    }\n\n    /**\n     * Copies another ellipse to this one.\n     * @example\n     * ```ts\n     * // Basic copying\n     * const source = new Ellipse(100, 100, 50, 25);\n     * const target = new Ellipse();\n     * target.copyFrom(source);\n     * ```\n     * @param ellipse - The ellipse to copy from\n     * @returns Returns itself\n     * @see {@link Ellipse.copyTo} For copying to another ellipse\n     * @see {@link Ellipse.clone} For creating new ellipse copy\n     */\n    public copyFrom(ellipse: Ellipse): this\n    {\n        this.x = ellipse.x;\n        this.y = ellipse.y;\n        this.halfWidth = ellipse.halfWidth;\n        this.halfHeight = ellipse.halfHeight;\n\n        return this;\n    }\n\n    /**\n     * Copies this ellipse to another one.\n     * @example\n     * ```ts\n     * // Basic copying\n     * const source = new Ellipse(100, 100, 50, 25);\n     * const target = new Ellipse();\n     * source.copyTo(target);\n     * ```\n     * @param ellipse - The ellipse to copy to\n     * @returns Returns given parameter\n     * @see {@link Ellipse.copyFrom} For copying from another ellipse\n     * @see {@link Ellipse.clone} For creating new ellipse copy\n     */\n    public copyTo(ellipse: Ellipse): Ellipse\n    {\n        ellipse.copyFrom(this);\n\n        return ellipse;\n    }\n\n    // #if _DEBUG\n    public toString(): string\n    {\n        return `[pixi.js/math:Ellipse x=${this.x} y=${this.y} halfWidth=${this.halfWidth} halfHeight=${this.halfHeight}]`;\n    }\n    // #endif\n}\n"],"names":[],"mappings":"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"}