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 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | 1x 1x 1x 1x 1x 1x 1x 3345x 3345x 3345x 3345x 3345x 3345x 3345x 3345x 3345x 3345x 3345x 3345x 3345x 3653x 3653x 3653x 1903x 1903x 1903x 1903x 3653x 1750x 1750x 1750x 1x 1x 1x 1x 1750x 1750x 3653x 3653x 3653x 3345x 3345x 3196x 656x 656x 3196x 3196x 3345x 2626x 1313x 1313x 1313x 1313x 2626x 3345x 2x 2x 3345x 3345x 2004x 7225x 7225x 1960x 2004x 3345x 1313x 1313x 1313x 1313x 1313x 1162x 1162x 1162x 1162x 887x 887x 887x 887x 887x 1313x 151x 151x 151x 151x 104x 104x 104x 104x 104x 151x 1313x 1313x 3345x 308x 308x 308x 308x 308x 308x 308x 308x 308x 308x 308x 3345x | import { Point } from './Point.js'; import { Shape } from './Shape.js'; export enum LineDirection { None = 0, Horizontal = 1, Vertical, } export class Line extends Shape { public from: Point; public to: Point; public direction: LineDirection = LineDirection.None; public length: number = 0; public intersections: Array<Point> = []; public gaps: Array<Line> = []; constructor(from: Point, to: Point) { super(); this.from = from; this.to = to; this.init(); } private init(): void { let from = this.from; let to = this.to; if (Math.abs(from.y - to.y) < Shape.tolerance) { this.direction = LineDirection.Horizontal; to.y = from.y; if (from.x > to.x) { const temp = from; from = to; to = temp; } this.length = to.x - from.x; } else if (Math.abs(from.x - to.x) < Shape.tolerance) { this.direction = LineDirection.Vertical; to.x = from.x; if (from.y > to.y) { const temp = from; from = to; to = temp; } this.length = to.y - from.y; } this.from = from; this.to = to; } private _valid: boolean | undefined = undefined; get valid(): boolean { if (this._valid === undefined) { this._valid = this.direction !== LineDirection.None && this.length > Shape.tolerance; } return this._valid; } get normalized(): Line { if (this.direction === LineDirection.Horizontal) { return new Line(new Point(this.from.x - Shape.tolerance, this.from.y), new Point(this.to.x + Shape.tolerance, this.from.y)); } else if (this.direction === LineDirection.Vertical) { return new Line(new Point(this.from.x, this.from.y - Shape.tolerance), new Point(this.from.x, this.to.y + Shape.tolerance)); } return this; } public addGap(line: Line): void { this.gaps.push(line); } public containsPoint(p: Point): boolean { if (this.direction === LineDirection.Vertical) { return this.from.x === p.x && p.y >= this.from.y && p.y <= this.to.y; } else if (this.direction === LineDirection.Horizontal) { return this.from.y === p.y && p.x >= this.from.x && p.x <= this.to.x; } return false; } // // todo implement // public containsLine(l:Line):boolean{ // if(this.direction === LineDirection.Vertical && l.direction === LineDirection.Vertical){ // return this.from.x === l.from.x // } // else if(this.direction === LineDirection.Horizontal && l.direction === LineDirection.Horizontal){ // return this.from.y === l.from.y // } // return false // } public addIntersectionPoint(point: Point): void { for (const intPoint of this.intersections) { if (intPoint.equal(point)) return; } this.intersections.push(point); } public intersection(line: Line): Point | undefined { let result: Point | undefined; if (!this.valid || !line.valid) { return result; } const thisNormalized = this.normalized; const lineNormalized = line.normalized; if (this.direction === LineDirection.Horizontal && line.direction === LineDirection.Vertical) { const x = lineNormalized.from.x; const y = thisNormalized.from.y; const isOk = x > thisNormalized.from.x && x < thisNormalized.to.x && y > lineNormalized.from.y && y < lineNormalized.to.y; if (isOk) { const intPoint = new Point(x, y); this.addIntersectionPoint(intPoint); line.addIntersectionPoint(intPoint); result = intPoint; } } else if (this.direction === LineDirection.Vertical && line.direction === LineDirection.Horizontal) { const x = thisNormalized.from.x; const y = lineNormalized.from.y; const isOk = x > lineNormalized.from.x && x < lineNormalized.to.x && y > thisNormalized.from.y && y < thisNormalized.to.y; if (isOk) { const intPoint = new Point(x, y); this.addIntersectionPoint(intPoint); line.addIntersectionPoint(intPoint); result = intPoint; } } // if(result){ // for (const gapLine of this.gaps) { // if(gapLine.containsPoint(result)) return undefined // } // // for (const gapLine of line.gaps) { // if(gapLine.containsPoint(result)) return undefined // } // } return result; } public transform(matrix: Array<number>): this { const p1 = this.from.transform(matrix); const p2 = this.to.transform(matrix); const x = Math.min(p1.x, p2.x); const y = Math.min(p1.y, p2.y); const width = Math.abs(p1.x - p2.x); const height = Math.abs(p1.y - p2.y); this.from = new Point(x, y); this.to = new Point(x + width, y + height); this.init(); return this; } } |