All files / src/elements/sector SectorConstructions.ts

97.52% Statements 118/121
89.74% Branches 35/39
94.44% Functions 17/18
97.52% Lines 118/121

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 1221x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1378x 66x 1378x 1378x 1x 66x 66x 66x 66x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1312x 45x 1312x 1312x 1x 45x 45x 45x 45x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1267x 1267x 1267x 1x 22x 22x 22x 1x 1x 1x 1x 1x 1x 1x 1245x 1245x 1245x 1x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1243x 1243x 1243x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1242x 1242x 1242x 1x       1x 1x 1x 1x 1x 1x 1x 1x 1x 1x  
/*----------------------------------------------------------------------+
|    Sector construction classes — extracted from Constructions.ts       |
+----------------------------------------------------------------------*/
 
import {Construction, ConstructionSignature, SortedParams, AllConstructions,
        SectorConstructions as SectorConstructionsEnum,
        GeomElementsForUpdate} from "../Constructions";
import {GeomElement} from "../GeomElement";
import {PlaneElement} from "../plane/PlaneElement";
import {PointElement} from "../point/PointElement";
import {SectorElement} from "./SectorElement";
import {ArcElement} from "./ArcElement";
import {AngleMarkerElement} from "./AngleMarkerElement";
 
// sector — points A, B, C [, plane D = screen]
// 2D: 3 points, 0 elements — uses screen plane
// 3D: 3 points, 1 PlaneElement — uses explicit plane
// (Java: Slate.java sector case 0 — new SectorElement(A,B,C,plane))
export class SectorConstruction extends Construction {
    constructionMethod: AllConstructions = SectorConstructionsEnum.sector;
    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 SectorElement({O:P[0], A:P[1], B:P[2], P: plane});
        return [[g], g];
    }
}
 
// sector — arc — points A, M, B [, plane D = screen]
// 2D: 3 points, 0 elements — uses screen plane
// 3D: 3 points, 1 PlaneElement — uses explicit plane
// (Java: Slate.java sector case 1 — new ArcElement(A,M,B,plane))
export class ArcConstruction extends Construction {
    constructionMethod: AllConstructions = SectorConstructionsEnum.arc;
    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 ArcElement(P[0], P[1], P[2], plane);
        return [[g], g];
    }
}
 
// angleMarker — vertex V, arm points P1, P2 [, int radiusPx]
// Marks the interior angle P1-V-P2 with a small fixed-radius sector
// (radius computed by the element, not the arm length). The optional
// integer overrides the default px radius. 2D screen-plane only for
// v1. (#91)
export class AngleMarkerConstruction extends Construction {
    constructionMethod: AllConstructions = SectorConstructionsEnum.angleMarker;
    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;
    }
    construct(screen: PlaneElement, P: PointElement[], E: GeomElement[], N: number[]): [GeomElementsForUpdate, GeomElement] {
        let g = new AngleMarkerElement(P[0], P[1], P[2], screen);
        return [[g], g];
    }
}
 
// angleMarker with an explicit px radius override.
export class AngleMarkerRadiusConstruction extends Construction {
    constructionMethod: AllConstructions = SectorConstructionsEnum.angleMarker;
    signature: ConstructionSignature = { points: 3, elements: 0, integers: 1 };
    public validateSignature(cm: AllConstructions, sp: SortedParams): boolean {
        if (cm !== this.constructionMethod) return false;
        return sp.P.length === 3 && sp.N.length === 1 && sp.E.length === 0;
    }
    construct(screen: PlaneElement, P: PointElement[], E: GeomElement[], N: number[]): [GeomElementsForUpdate, GeomElement] {
        let g = new AngleMarkerElement(P[0], P[1], P[2], screen, N[0]);
        return [[g], g];
    }
}
 
// angleMarkerReflex — same as angleMarker but draws the major (reflex,
// > 180°) arc. Rare; Euclid avoids reflex angles, so this is for the
// occasional teaching case (a III.20-style central angle). (#91)
export class AngleMarkerReflexConstruction extends Construction {
    constructionMethod: AllConstructions = SectorConstructionsEnum.angleMarkerReflex;
    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;
    }
    construct(screen: PlaneElement, P: PointElement[], E: GeomElement[], N: number[]): [GeomElementsForUpdate, GeomElement] {
        let g = new AngleMarkerElement(P[0], P[1], P[2], screen, undefined, true);
        return [[g], g];
    }
}
 
export class AngleMarkerReflexRadiusConstruction extends Construction {
    constructionMethod: AllConstructions = SectorConstructionsEnum.angleMarkerReflex;
    signature: ConstructionSignature = { points: 3, elements: 0, integers: 1 };
    public validateSignature(cm: AllConstructions, sp: SortedParams): boolean {
        if (cm !== this.constructionMethod) return false;
        return sp.P.length === 3 && sp.N.length === 1 && sp.E.length === 0;
    }
    construct(screen: PlaneElement, P: PointElement[], E: GeomElement[], N: number[]): [GeomElementsForUpdate, GeomElement] {
        let g = new AngleMarkerElement(P[0], P[1], P[2], screen, N[0], true);
        return [[g], g];
    }
}
 
export const sectorConstructions: Construction[] = [
    new SectorConstruction(),
    new ArcConstruction(),
    new AngleMarkerConstruction(),
    new AngleMarkerRadiusConstruction(),
    new AngleMarkerReflexConstruction(),
    new AngleMarkerReflexRadiusConstruction(),
];