Skip to content

Commit b8298c9

Browse files
committed
test(s2): Cell.distanceToEdge
1 parent 04cea21 commit b8298c9

File tree

1 file changed

+60
-56
lines changed

1 file changed

+60
-56
lines changed

s2/Cell_test.ts

Lines changed: 60 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -409,26 +409,26 @@ describe('s2.Cell', () => {
409409
}
410410
})
411411

412-
// function chooseEdgeNearCell(cell: Cell): [Point, Point] {
413-
// const c = cell.capBound()
414-
// let a: Point, b: Point
415-
416-
// if (Math.random() < 0.2) {
417-
// a = randomPoint()
418-
// } else {
419-
// a = samplePointFromCap(Cap.fromCenterChordAngle(c.center, 1.5 * c.rad))
420-
// }
412+
function chooseEdgeNearCell(cell: Cell): [Point, Point] {
413+
const c = cell.capBound()
414+
let a: Point, b: Point
415+
416+
if (Math.random() < 0.2) {
417+
a = randomPoint()
418+
} else {
419+
a = samplePointFromCap(Cap.fromCenterChordAngle(c.center, 1.5 * c.rad))
420+
}
421421

422-
// const maxLength = Math.min(100 * Math.pow(1e-4, Math.random()) * c.radius(), Math.PI / 2)
423-
// b = samplePointFromCap(Cap.fromCenterAngle(a, maxLength))
422+
const maxLength = Math.min(100 * Math.pow(1e-4, Math.random()) * c.radius(), Math.PI / 2)
423+
b = samplePointFromCap(Cap.fromCenterAngle(a, maxLength))
424424

425-
// if (Math.random() < 0.05) {
426-
// a = Point.fromVector(a.vector.mul(-1))
427-
// b = Point.fromVector(b.vector.mul(-1))
428-
// }
425+
if (Math.random() < 0.05) {
426+
a = Point.fromVector(a.vector.mul(-1))
427+
b = Point.fromVector(b.vector.mul(-1))
428+
}
429429

430-
// return [a, b]
431-
// }
430+
return [a, b]
431+
}
432432

433433
function minDistanceToPointBruteForce(cell: Cell, target: Point): ChordAngle {
434434
let minDistance = chordangle.infChordAngle()
@@ -449,22 +449,22 @@ describe('s2.Cell', () => {
449449
return maxDistance
450450
}
451451

452-
// function minDistanceToEdgeBruteForce(cell: Cell, a: Point, b: Point): ChordAngle {
453-
// if (cell.containsPoint(a) || cell.containsPoint(b)) return 0
452+
function minDistanceToEdgeBruteForce(cell: Cell, a: Point, b: Point): ChordAngle {
453+
if (cell.containsPoint(a) || cell.containsPoint(b)) return 0
454454

455-
// let minDist = chordangle.infChordAngle()
456-
// for (let i = 0; i < 4; i++) {
457-
// const v0 = cell.vertex(i)
458-
// const v1 = cell.vertex((i + 1) % 4)
455+
let minDist = chordangle.infChordAngle()
456+
for (let i = 0; i < 4; i++) {
457+
const v0 = cell.vertex(i)
458+
const v1 = cell.vertex((i + 1) % 4)
459459

460-
// if (crossingSign(a, b, v0, v1) !== DO_NOT_CROSS) return 0
460+
if (crossingSign(a, b, v0, v1) !== DO_NOT_CROSS) return 0
461461

462-
// minDist = updateMinDistance(a, v0, v1, minDist)[0]
463-
// minDist = updateMinDistance(b, v0, v1, minDist)[0]
464-
// minDist = updateMinDistance(v0, a, b, minDist)[0]
465-
// }
466-
// return minDist
467-
// }
462+
minDist = updateMinDistance(a, v0, v1, minDist).dist
463+
minDist = updateMinDistance(b, v0, v1, minDist).dist
464+
minDist = updateMinDistance(v0, a, b, minDist).dist
465+
}
466+
return minDist
467+
}
468468

469469
function maxDistanceToEdgeBruteForce(cell: Cell, a: Point, b: Point): ChordAngle {
470470
if (
@@ -479,44 +479,48 @@ describe('s2.Cell', () => {
479479
const v0 = cell.vertex(i)
480480
const v1 = cell.vertex((i + 1) % 4)
481481

482+
// If the antipodal edge crosses through the cell, min distance is Pi.
482483
if (
483484
crossingSign(Point.fromVector(a.vector.mul(-1)), Point.fromVector(b.vector.mul(-1)), v0, v1) !== DO_NOT_CROSS
484485
) {
485486
return STRAIGHT_CHORDANGLE
486487
}
487488

488-
maxDist = updateMaxDistance(a, v0, v1, maxDist)[0]
489-
maxDist = updateMaxDistance(b, v0, v1, maxDist)[0]
490-
maxDist = updateMaxDistance(v0, a, b, maxDist)[0]
489+
maxDist = updateMaxDistance(a, v0, v1, maxDist).dist
490+
maxDist = updateMaxDistance(b, v0, v1, maxDist).dist
491+
maxDist = updateMaxDistance(v0, a, b, maxDist).dist
491492
}
492493
return maxDist
493494
}
494495

495-
// test('distanceToEdge', () => {
496-
// for (let iter = 0; iter < 1000; iter++) {
497-
// const cell = Cell.fromCellID(randomCellID())
498-
499-
// const [a, b] = chooseEdgeNearCell(cell)
500-
// const expectedMin = chordangle.angle(minDistanceToEdgeBruteForce(cell, a, b))
501-
// const expectedMax = chordangle.angle(maxDistanceToEdgeBruteForce(cell, a, b))
502-
// const actualMin = chordangle.angle(cell.distanceToEdge(a, b))
503-
// const actualMax = chordangle.angle(cell.maxDistanceToEdge(a, b))
504-
505-
// let expectedError = 1e-12
506-
// if (expectedMin > Math.PI / 2) {
507-
// expectedError = 2e-8
508-
// } else if (expectedMin <= Math.PI / 3) {
509-
// expectedError = 1e-15
510-
// }
496+
test('distanceToEdge', () => {
497+
for (let iter = 0; iter < 1000; iter++) {
498+
const cell = Cell.fromCellID(randomCellID())
511499

512-
// ok(float64Near(expectedMin, actualMin, expectedError))
513-
// ok(float64Near(expectedMax, actualMax, 1e-12))
500+
const [a, b] = chooseEdgeNearCell(cell)
501+
const expectedMin = chordangle.angle(minDistanceToEdgeBruteForce(cell, a, b))
502+
const expectedMax = chordangle.angle(maxDistanceToEdgeBruteForce(cell, a, b))
503+
const actualMin = chordangle.angle(cell.distanceToEdge(a, b))
504+
const actualMax = chordangle.angle(cell.maxDistanceToEdge(a, b))
505+
506+
// The error has a peak near Pi/2 for edge distance, and another peak near
507+
// Pi for vertex distance.
508+
let expectedError = 1e-12
509+
if (expectedMin > Math.PI / 2) {
510+
// Max error for ChordAngle as it approaches Pi is about 3e-8.
511+
expectedError = 3e-8
512+
} else if (expectedMin <= Math.PI / 3) {
513+
expectedError = 1e-15
514+
}
514515

515-
// if (expectedMax <= Math.PI / 3) {
516-
// ok(float64Near(expectedMax, actualMax, 1e-15))
517-
// }
518-
// }
519-
// })
516+
ok(float64Near(expectedMin, actualMin, expectedError))
517+
ok(float64Near(expectedMax, actualMax, 1e-12))
518+
519+
if (expectedMax <= Math.PI / 3) {
520+
ok(float64Near(expectedMax, actualMax, 1e-15))
521+
}
522+
}
523+
})
520524

521525
test('maxDistanceToEdge', () => {
522526
const cell = Cell.fromCellID(cellid.fromFacePosLevel(0, 0n, 20))

0 commit comments

Comments
 (0)