All files / src/elements/circle CircleConstructions.ts

100% Statements 101/101
100% Branches 23/23
100% Functions 10/10
100% Lines 101/101

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 1021x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1670x 367x 1670x 1670x 1x 367x 367x 367x 367x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1748x 1748x 1748x 1748x 1x 78x 78x 78x 78x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 5x 5x 5x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 11x 11x 11x 1x 1x 1x 1x 1x 1x 1x 1x  
/*----------------------------------------------------------------------+
|    Circle construction classes — extracted from Constructions.ts       |
|    Note: CircumcircleConstruction lives in point/PointConstructions.ts |
|    because CircumcenterConstruction extends it directly.              |
+----------------------------------------------------------------------*/
 
import {Construction, ConstructionSignature, SortedParams, AllConstructions,
        CircleConstructions as CircleConstructionsEnum,
        GeomElementsForUpdate} from "../Constructions";
import {GeomElement} from "../GeomElement";
import {CircleElement} from "./CircleElement";
import {InvertCircleElement} from "./InvertCircleElement";
import {SphereIntersectionElement} from "./SphereIntersectionElement";
import {PlaneElement} from "../plane/PlaneElement";
import {PointElement} from "../point/PointElement";
import {SphereElement} from "../sphere/SphereElement";
 
/************************
 * Element Class Circle *
 ************************/
 
// circle
// radius — points A, B [, plane C = screen]
// the circle with center A and radius AB in the plane C
// 2D: 2 points, 0 elements — uses screen plane
// 3D: 2 points, 1 PlaneElement — uses explicit plane
// (Java: Slate.java circle case 0 — new CircleElement(A,B,plane))
export class CircleRadiusCenterConstruction extends Construction {
    constructionMethod: AllConstructions = CircleConstructionsEnum.radius;
    signature: ConstructionSignature = { points: 2, elements: 0, integers: 0 };
    public validateSignature(cm: AllConstructions, sp: SortedParams): boolean {
        if (cm !== this.constructionMethod) return false;
        return sp.P.length === 2 && sp.N.length === 0
            && (sp.E.length === 0 || (sp.E.length === 1 && sp.E[0] instanceof PlaneElement));
    }
    construct(screen: PlaneElement, P: PointElement[], E: GeomElement[], N: number[]): [GeomElementsForUpdate, GeomElement] {
        let plane = E.length > 0 ? E[0] as PlaneElement : screen;
        let g = new CircleElement({C:P[0], B:P[1], AP:plane});
        return [[g], g];
    }
}
 
// circle — radius (3-point) — points A, B, C [, plane D = screen]
// the circle with center A and radius |BC| in the plane D
// 2D: 3 points, 0 elements — uses screen plane
// 3D: 3 points, 1 PlaneElement — uses explicit plane
// MUST be registered BEFORE the 2-point variant in the constructions array
// (signature variant ordering rule: longer signature first)
// (Java: Slate.java circle case 0 — new CircleElement(A,B,C,plane))
export class CircleRadius3PointConstruction extends Construction {
    constructionMethod: AllConstructions = CircleConstructionsEnum.radius;
    signature: ConstructionSignature = { points: 3, elements: 0, integers: 0 };
    public validateSignature(cm: AllConstructions, sp: SortedParams): boolean {
        if (cm !== this.constructionMethod) return false;
        return sp.P.length === 3 && sp.N.length === 0
            && (sp.E.length === 0 || (sp.E.length === 1 && sp.E[0] instanceof PlaneElement));
    }
    construct(screen: PlaneElement, P: PointElement[], E: GeomElement[], N: number[]): [GeomElementsForUpdate, GeomElement] {
        let plane = E.length > 0 ? E[0] as PlaneElement : screen;
        let g = new CircleElement({C: P[0], A: P[1], B: P[2], AP: plane});
        return [[g], g];
    }
}
 
 
// circle
// invert
// circles A, B
// the image of circle A inverted in circle B
// (Java: InvertCircle.java — TS: InvertCircleElement.ts)
export class InvertCircleConstruction extends Construction {
    constructionMethod: AllConstructions = CircleConstructionsEnum.invert;
    signature = { points: 0, elements: 2, integers: 0, elementTypes: [CircleElement, CircleElement] };
 
    construct(screen: PlaneElement, P: PointElement[], E: GeomElement[], N: number[]): [GeomElementsForUpdate, GeomElement] {
        const g = new InvertCircleElement(E[0] as CircleElement, E[1] as CircleElement);
        return [[g], g];
    }
}
 
// circle
// intersection
// spheres A, B
// the circle at the intersection of spheres A and B
// (Java: IntersectionSS.java — TS: SphereIntersectionElement.ts)
export class SphereIntersectionConstruction extends Construction {
    constructionMethod: AllConstructions = CircleConstructionsEnum.intersection;
    signature = { points: 0, elements: 2, integers: 0, elementTypes: [SphereElement, SphereElement] };
 
    construct(screen: PlaneElement, P: PointElement[], E: GeomElement[], N: number[]): [GeomElementsForUpdate, GeomElement] {
        const g = new SphereIntersectionElement(E[0] as SphereElement, E[1] as SphereElement);
        return [[g], g];
    }
}
 
export const circleConstructions: Construction[] = [
    new CircleRadius3PointConstruction(),
    new CircleRadiusCenterConstruction(),
    new InvertCircleConstruction(),
    new SphereIntersectionConstruction(),
];