Skip to content

Commit

Permalink
Add Extent.extendSelf(other) as a mutable version of Extent.extend(ot…
Browse files Browse the repository at this point in the history
…her)

(closes #268)
  • Loading branch information
bhousel committed Feb 21, 2024
1 parent d199102 commit f339005
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 15 deletions.
39 changes: 34 additions & 5 deletions packages/math/src/Extent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,11 +229,40 @@ export class Extent {
* const c = a.extend(b); // returns new Extent { min: [ 0, -1 ], max: [ 5, 10 ] }
* ```
*/
extend(other: Extent): Extent {
return new Extent(
[Math.min(other.min[0], this.min[0]), Math.min(other.min[1], this.min[1])],
[Math.max(other.max[0], this.max[0]), Math.max(other.max[1], this.max[1])]
);
extend(other: Extent | Vec2): Extent {
if (other instanceof Extent) {
return new Extent(
[Math.min(other.min[0], this.min[0]), Math.min(other.min[1], this.min[1])],
[Math.max(other.max[0], this.max[0]), Math.max(other.max[1], this.max[1])]
);
} else {
return new Extent(
[Math.min(other[0], this.min[0]), Math.min(other[1], this.min[1])],
[Math.max(other[0], this.max[0]), Math.max(other[1], this.max[1])]
);
}
}

/** Extend the bounds of an extent, modifying self
* This is like `extend` but modifies self, instead of returning a `new Extent`
* This option is slightly more performant for situations where you don't mind mutating the Extent.
* @param other
* @returns this Extent
* @example ```
* const a = new Extent([0, 0], [5, 10]);
* const b = new Extent([4, -1], [5, 10]);
* const c = a.extendSelf(b); // a is extended, { min: [ 0, -1 ], max: [ 5, 10 ] }, b unchanged
* ```
*/
extendSelf(other: Extent | Vec2): Extent {
if (other instanceof Extent) {
this.min = [Math.min(other.min[0], this.min[0]), Math.min(other.min[1], this.min[1])];
this.max = [Math.max(other.max[0], this.max[0]), Math.max(other.max[1], this.max[1])];
} else {
this.min = [Math.min(other[0], this.min[0]), Math.min(other[1], this.min[1])];
this.max = [Math.max(other[0], this.max[0]), Math.max(other[1], this.max[1])];
}
return this;
}

/** Returns a new Extent representing the current extent
Expand Down
4 changes: 1 addition & 3 deletions packages/math/src/Viewport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,7 @@ export class Viewport {
const extent = new Extent();

for (let i = 0; i < polygon.length - 1; i++) { // skip last point, it's first point repeated
const loc: Vec2 = this.unproject(polygon[i]);
extent.min = [Math.min(loc[0], extent.min[0]), Math.min(loc[1], extent.min[1])];
extent.max = [Math.max(loc[0], extent.max[0]), Math.max(loc[1], extent.max[1])];
extent.extendSelf(this.unproject(polygon[i]));
}
return extent;
}
Expand Down
56 changes: 49 additions & 7 deletions packages/math/test/Extent.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,26 +128,32 @@ describe('math/extent', () => {
});

describe('#extend', () => {
it('does not modify self', () => {
it('does not modify self or other', () => {
const a = new Extent([0, 0], [0, 0]);
const b = new Extent([1, 1]);
a.extend(b);
const c = a.extend(b);
assert.notEqual(a, b);
assert.deepEqual(a.max, [0, 0]);
assert.notEqual(a, c);
assert.notEqual(b, c);
assert.deepEqual(a.max, [0, 0]); // 'a' unchanged
assert.deepEqual(b.min, [1, 1]); // 'b' unchanged
});

it('returns the minimal extent containing self and the given point', () => {
it('returns the minimal extent containing self and the given Vec2', () => {
const a = new Extent();
const b = a.extend(new Extent([0, 0]));
assert.deepEqual(a.min, [Infinity, Infinity]);
assert.deepEqual(a.max, [-Infinity, -Infinity]);

const b = a.extend([0, 0]);
assert.deepEqual(b.min, [0, 0]);
assert.deepEqual(b.max, [0, 0]);

const c = b.extend(new Extent([5, 10]));
const c = b.extend([5, 10]);
assert.deepEqual(c.min, [0, 0]);
assert.deepEqual(c.max, [5, 10]);
});

it('returns the minimal extent containing self and the given extent', () => {
it('returns the minimal extent containing self and the given Extent', () => {
const a = new Extent([0, 0], [5, 10]);
const b = new Extent([4, -1], [5, 10]);
const c = a.extend(b);
Expand All @@ -156,6 +162,42 @@ describe('math/extent', () => {
});
});


describe('#extendSelf', () => {
it('modifies self, but not other', () => {
const a = new Extent([0, 0], [0, 0]);
const b = new Extent([1, 1]);
const c = a.extendSelf(b);
assert.notEqual(a, b);
assert.equal(a, c); // a === c
assert.notEqual(b, c);
assert.deepEqual(a.max, [1, 1]); // 'a' changed
assert.deepEqual(b.min, [1, 1]); // 'b' unchanged
});

it('returns the minimal extent containing self and the given Vec2', () => {
const a = new Extent();
assert.deepEqual(a.min, [Infinity, Infinity]);
assert.deepEqual(a.max, [-Infinity, -Infinity]);

a.extendSelf([0, 0]);
assert.deepEqual(a.min, [0, 0]);
assert.deepEqual(a.max, [0, 0]);

a.extendSelf([5, 10]);
assert.deepEqual(a.min, [0, 0]);
assert.deepEqual(a.max, [5, 10]);
});

it('returns the minimal extent containing self and the given Extent', () => {
const a = new Extent([0, 0], [5, 10]);
const b = new Extent([4, -1], [5, 10]);
a.extendSelf(b);
assert.deepEqual(a.min, [0, -1]);
assert.deepEqual(a.max, [5, 10]);
});
});

describe('#contains', () => {
it('returns true for a point inside self', () => {
const a = new Extent([0, 0], [5, 5]);
Expand Down

0 comments on commit f339005

Please sign in to comment.