-
Notifications
You must be signed in to change notification settings - Fork 74
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[dropper,rect,tests] Separate rectangle functions to own library
Separate all rectangle functions to its own class Rect and rewrite of most during the process. Basic unit tests provided so we can catch bugs easier. So far works much better then previous implementation.
- Loading branch information
Showing
3 changed files
with
219 additions
and
87 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import Rect from '../rect' | ||
|
||
const dw = 1680 | ||
const dh = 930 | ||
|
||
const rA = new Rect(0, 0, dw, dh) | ||
const rB = new Rect(0, 100, dw, dh) | ||
const rC = new Rect(50, 20, 100, 70) | ||
const rD = new Rect(0, 1000, dw, dh) | ||
const rE = new Rect(0, 900, dw, dh) | ||
|
||
const rX = new Rect(173, 0, dw, dh) | ||
const rY = new Rect(1700, 0, dw, dh) | ||
|
||
const rAB = new Rect(0, 0, dw, 1030) | ||
const rAE = new Rect(0, 0, dw, 1830) | ||
const rAED = new Rect(0, 0, dw, 1930) | ||
|
||
const rAX = new Rect(0, 0, dw + 173, dh) | ||
const rAXY = new Rect(0, 0, dw + 1700, dh) | ||
|
||
const rCt = new Rect(20, 50, 70, 100) | ||
|
||
// FIXME: add horizontal merge tests | ||
|
||
test('rA right', () => { | ||
expect(rA.right).toBe(dw) | ||
}) | ||
|
||
test('rC bottom', () => { | ||
expect(rC.bottom).toBe(90) | ||
}) | ||
|
||
test('rB should not be contained in rA', () => { | ||
expect(rA.contains(rB)).toBe(false) | ||
}) | ||
|
||
test('merge of rA and rB equal to rAB', () => { | ||
expect(rA.merge(rB)).toStrictEqual(rAB) | ||
}) | ||
|
||
test('cannot merge rA and rD', () => { | ||
expect(rA.merge(rD)).toBeNull() | ||
}) | ||
|
||
test('can merge rA with rE and then with rD', () => { | ||
const m = rA.merge(rE) | ||
expect(m).toStrictEqual(rAE) | ||
expect(m.merge(rD)).toStrictEqual(rAED) | ||
}) | ||
|
||
test('transposed rC', () => { | ||
expect(rC.transposed()).toStrictEqual(rCt) | ||
}) | ||
|
||
test('double transposed rC should be rC', () => { | ||
expect(rC.transposed().transposed()).toStrictEqual(rC) | ||
}) | ||
|
||
test('can merge rA with rX', () => { | ||
expect(rA.merge(rX)).toStrictEqual(rAX) | ||
}) | ||
|
||
test('cannot merge rA with rY', () => { | ||
expect(rA.merge(rY)).toBeNull() | ||
}) | ||
|
||
test('can merge rA with rX and then rY', () => { | ||
const m = rA.merge(rX) | ||
expect(m).toStrictEqual(rAX) | ||
expect(m.merge(rY)).toStrictEqual(rAXY) | ||
}) | ||
|
||
test('cannot merge horizontally and vertically different', () => { | ||
expect(rC.merge(rX)).toBeNull() | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
class Rect { | ||
left: number | ||
top: number | ||
right: number | ||
bottom: number | ||
width: number | ||
height: number | ||
|
||
constructor(left, top, width, height) { | ||
this.left = left | ||
this.top = top | ||
this.right = left + width | ||
this.bottom = top + height | ||
this.width = width | ||
this.height = height | ||
} | ||
|
||
transposed() { | ||
return new Rect(this.top, this.left, this.height, this.width) | ||
} | ||
|
||
contains(other: Rect): boolean { | ||
return ( | ||
other.left >= this.left && | ||
other.right <= this.right && | ||
other.top >= this.top && | ||
other.bottom <= this.bottom | ||
) | ||
} | ||
|
||
horizontalMerge(other) { | ||
const A = this.transposed() | ||
const B = other.transposed() | ||
|
||
const X = A.verticalMerge(B) | ||
if (X === null) { | ||
return null | ||
} | ||
|
||
return X.transposed() | ||
} | ||
|
||
verticalMerge(other) { | ||
let A = this | ||
let B = other | ||
|
||
// swap A and B if A is not on top | ||
if (this.top > other.top) { | ||
;[A, B] = [B, A] | ||
} | ||
|
||
// if A is overlapping with B | ||
if (A.bottom >= B.top && A.bottom <= B.bottom) { | ||
return new Rect(A.left, A.top, A.right - A.left, B.bottom - A.top) | ||
} else { | ||
return null | ||
} | ||
} | ||
|
||
merge(other: Rect): Rect { | ||
let x, y, w, h: number | ||
|
||
// same left and right | ||
if (this.left == other.left && this.right == other.right) { | ||
return this.verticalMerge(other) | ||
// same top and bottom | ||
} else if (this.top == other.top && this.bottom == other.bottom) { | ||
return this.horizontalMerge(other) | ||
} | ||
|
||
return null | ||
} | ||
|
||
toString(): string { | ||
return `Rect(${this.width}x${this.height})@${this.left},${this.top}` | ||
} | ||
} | ||
|
||
export default Rect |