{"version":3,"file":"Triangle.mjs","sources":["../../../src/maths/shapes/Triangle.ts"],"sourcesContent":["import { squaredDistanceToLineSegment } from '../misc/squaredDistanceToLineSegment';\nimport { Rectangle } from './Rectangle';\n\nimport type { SHAPE_PRIMITIVE } from '../misc/const';\nimport type { ShapePrimitive } from './ShapePrimitive';\n\n/**\n * A class to define a shape of a triangle via user defined coordinates.\n *\n * Used for creating triangular shapes and hit areas with three points (x,y), (x2,y2), (x3,y3).\n * Points are stored in counter-clockwise order.\n * @example\n * ```ts\n * // Basic triangle creation\n * const triangle = new Triangle(0, 0, 100, 0, 50, 50);\n * // Use as hit area\n * container.hitArea = new Triangle(0, 0, 100, 0, 50, 100);\n * // Check point containment\n * const isInside = triangle.contains(mouseX, mouseY);\n * // Get bounding box\n * const bounds = triangle.getBounds();\n * ```\n * @see {@link Rectangle} For rectangular shapes\n * @see {@link Circle} For circular shapes\n * @see {@link Polygon} For complex shapes\n * @category maths\n * @standard\n */\nexport class Triangle implements ShapePrimitive\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 Triangle(0, 0, 100, 0, 50, 100);\n     * console.log(shape.type); // 'triangle'\n     *\n     * // Use in type guards\n     * if (shape.type === 'triangle') {\n     *     console.log(shape.x2, shape.y2);\n     * }\n     * ```\n     * @readonly\n     * @default 'triangle'\n     * @see {@link SHAPE_PRIMITIVE} For all shape types\n     */\n    public readonly type: SHAPE_PRIMITIVE = 'triangle';\n\n    /**\n     * The X coordinate of the first point of the triangle.\n     * @example\n     * ```ts\n     * // Set first point x position\n     * const triangle = new Triangle();\n     * triangle.x = 100;\n     * ```\n     * @default 0\n     */\n    public x: number;\n\n    /**\n     * The Y coordinate of the first point of the triangle.\n     * @example\n     * ```ts\n     * // Set first point y position\n     * const triangle = new Triangle();\n     * triangle.y = 100;\n     * ```\n     * @default 0\n     */\n    public y: number;\n\n    /**\n     * The X coordinate of the second point of the triangle.\n     * @example\n     * ```ts\n     * // Create horizontal line for second point\n     * const triangle = new Triangle(0, 0);\n     * triangle.x2 = triangle.x + 100; // 100 units to the right\n     * ```\n     * @default 0\n     */\n    public x2: number;\n\n    /**\n     * The Y coordinate of the second point of the triangle.\n     * @example\n     * ```ts\n     * // Create vertical line for second point\n     * const triangle = new Triangle(0, 0);\n     * triangle.y2 = triangle.y + 100; // 100 units down\n     * ```\n     * @default 0\n     */\n    public y2: number;\n\n    /**\n     * The X coordinate of the third point of the triangle.\n     * @example\n     * ```ts\n     * // Create equilateral triangle\n     * const triangle = new Triangle(0, 0, 100, 0);\n     * triangle.x3 = 50;  // Middle point x\n     * triangle.y3 = 86.6; // Height using sin(60°)\n     * ```\n     * @default 0\n     */\n    public x3: number;\n\n    /**\n     * The Y coordinate of the third point of the triangle.\n     * @example\n     * ```ts\n     * // Create right triangle\n     * const triangle = new Triangle(0, 0, 100, 0);\n     * triangle.x3 = 0;   // Align with first point\n     * triangle.y3 = 100; // 100 units down\n     * ```\n     * @default 0\n     */\n    public y3: number;\n\n    /**\n     * @param x - The X coord of the first point.\n     * @param y - The Y coord of the first point.\n     * @param x2 - The X coord of the second point.\n     * @param y2 - The Y coord of the second point.\n     * @param x3 - The X coord of the third point.\n     * @param y3 - The Y coord of the third point.\n     */\n    constructor(x = 0, y = 0, x2 = 0, y2 = 0, x3 = 0, y3 = 0)\n    {\n        this.x = x;\n        this.y = y;\n        this.x2 = x2;\n        this.y2 = y2;\n        this.x3 = x3;\n        this.y3 = y3;\n    }\n\n    /**\n     * Checks whether the x and y coordinates given are contained within this triangle\n     * @example\n     * ```ts\n     * // Basic containment check\n     * const triangle = new Triangle(0, 0, 100, 0, 50, 100);\n     * const isInside = triangle.contains(25, 25); // true\n     * ```\n     * @remarks\n     * - Uses barycentric coordinate system\n     * - Works with any triangle shape\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 coordinates are within this Triangle\n     * @see {@link Triangle.strokeContains} For checking stroke intersection\n     * @see {@link Triangle.getBounds} For getting containing rectangle\n     */\n    public contains(x: number, y: number): boolean\n    {\n        const s = ((this.x - this.x3) * (y - this.y3)) - ((this.y - this.y3) * (x - this.x3));\n        const t = ((this.x2 - this.x) * (y - this.y)) - ((this.y2 - this.y) * (x - this.x));\n\n        if ((s < 0) !== (t < 0) && s !== 0 && t !== 0) { return false; }\n\n        const d = ((this.x3 - this.x2) * (y - this.y2)) - ((this.y3 - this.y2) * (x - this.x2));\n\n        return d === 0 || (d < 0) === (s + t <= 0);\n    }\n\n    /**\n     * Checks whether the x and y coordinates given are contained within this triangle including the stroke.\n     * @example\n     * ```ts\n     * // Basic stroke check\n     * const triangle = new Triangle(0, 0, 100, 0, 50, 100);\n     * const isOnStroke = triangle.strokeContains(25, 25, 4); // 4px line width\n     *\n     * // Check with different alignments\n     * const innerStroke = triangle.strokeContains(25, 25, 4, 1);   // Inside\n     * const centerStroke = triangle.strokeContains(25, 25, 4, 0.5); // Centered\n     * const outerStroke = triangle.strokeContains(25, 25, 4, 0);   // Outside\n     * ```\n     * @param pointX - The X coordinate of the point to test\n     * @param pointY - 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 coordinates are within this triangle's stroke\n     * @see {@link Triangle.contains} For checking fill containment\n     * @see {@link Triangle.getBounds} For getting stroke bounds\n     */\n    public strokeContains(pointX: number, pointY: number, strokeWidth: number, _alignment: number = 0.5): boolean\n    {\n        const halfStrokeWidth = strokeWidth / 2;\n        const halfStrokeWidthSquared = halfStrokeWidth * halfStrokeWidth;\n\n        const { x, x2, x3, y, y2, y3 } = this;\n\n        if (squaredDistanceToLineSegment(pointX, pointY, x, y, x2, y3) <= halfStrokeWidthSquared\n            || squaredDistanceToLineSegment(pointX, pointY, x2, y2, x3, y3) <= halfStrokeWidthSquared\n            || squaredDistanceToLineSegment(pointX, pointY, x3, y3, x, y) <= halfStrokeWidthSquared)\n        {\n            return true;\n        }\n\n        return false;\n    }\n\n    /**\n     * Creates a clone of this Triangle\n     * @example\n     * ```ts\n     * // Basic cloning\n     * const original = new Triangle(0, 0, 100, 0, 50, 100);\n     * const copy = original.clone();\n     *\n     * // Clone and modify\n     * const modified = original.clone();\n     * modified.x3 = 75;\n     * modified.y3 = 150;\n     *\n     * // Verify independence\n     * console.log(original.y3);  // 100\n     * console.log(modified.y3);  // 150\n     * ```\n     * @returns A copy of the triangle\n     * @see {@link Triangle.copyFrom} For copying into existing triangle\n     * @see {@link Triangle.copyTo} For copying to another triangle\n     */\n    public clone(): Triangle\n    {\n        const triangle = new Triangle(\n            this.x,\n            this.y,\n            this.x2,\n            this.y2,\n            this.x3,\n            this.y3\n        );\n\n        return triangle;\n    }\n\n    /**\n     * Copies another triangle to this one.\n     * @example\n     * ```ts\n     * // Basic copying\n     * const source = new Triangle(0, 0, 100, 0, 50, 100);\n     * const target = new Triangle();\n     * target.copyFrom(source);\n     *\n     * // Chain with other operations\n     * const triangle = new Triangle()\n     *     .copyFrom(source)\n     *     .getBounds(rect);\n     * ```\n     * @param triangle - The triangle to copy from\n     * @returns Returns itself\n     * @see {@link Triangle.copyTo} For copying to another triangle\n     * @see {@link Triangle.clone} For creating new triangle copy\n     */\n    public copyFrom(triangle: Triangle): this\n    {\n        this.x = triangle.x;\n        this.y = triangle.y;\n        this.x2 = triangle.x2;\n        this.y2 = triangle.y2;\n        this.x3 = triangle.x3;\n        this.y3 = triangle.y3;\n\n        return this;\n    }\n\n    /**\n     * Copies this triangle to another one.\n     * @example\n     * ```ts\n     * // Basic copying\n     * const source = new Triangle(0, 0, 100, 0, 50, 100);\n     * const target = new Triangle();\n     * source.copyTo(target);\n     *\n     * // Chain with other operations\n     * const result = source\n     *     .copyTo(new Triangle())\n     *     .getBounds();\n     * ```\n     * @remarks\n     * - Updates target triangle values\n     * - Copies all point coordinates\n     * - Returns target for chaining\n     * - More efficient than clone()\n     * @param triangle - The triangle to copy to\n     * @returns Returns given parameter\n     * @see {@link Triangle.copyFrom} For copying from another triangle\n     * @see {@link Triangle.clone} For creating new triangle copy\n     */\n    public copyTo(triangle: Triangle): Triangle\n    {\n        triangle.copyFrom(this);\n\n        return triangle;\n    }\n\n    /**\n     * Returns the framing rectangle of the triangle as a Rectangle object\n     * @example\n     * ```ts\n     * // Basic bounds calculation\n     * const triangle = new Triangle(0, 0, 100, 0, 50, 100);\n     * const bounds = triangle.getBounds();\n     * // bounds: x=0, y=0, width=100, height=100\n     *\n     * // Reuse existing rectangle\n     * const rect = new Rectangle();\n     * triangle.getBounds(rect);\n     * ```\n     * @param out - Optional rectangle to store the result\n     * @returns The framing rectangle\n     * @see {@link Rectangle} For rectangle properties\n     * @see {@link Triangle.contains} For checking if a point is inside\n     */\n    public getBounds(out?: Rectangle): Rectangle\n    {\n        out ||= new Rectangle();\n\n        const minX = Math.min(this.x, this.x2, this.x3);\n        const maxX = Math.max(this.x, this.x2, this.x3);\n        const minY = Math.min(this.y, this.y2, this.y3);\n        const maxY = Math.max(this.y, this.y2, this.y3);\n\n        out.x = minX;\n        out.y = minY;\n        out.width = maxX - minX;\n        out.height = maxY - minY;\n\n        return out;\n    }\n}\n"],"names":[],"mappings":"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"}