@js-draw/math
Version:
A math library for js-draw.
64 lines (51 loc) • 2.3 kB
text/typescript
import { Vec2 } from '../Vec2';
import Triangle from './Triangle';
describe('Triangle', () => {
describe('signed distance function should return correct values', () => {
it('signed distance function should be zero along the boundary of a shape', () => {
const testTriangle = Triangle.fromVertices(Vec2.of(-1, -1), Vec2.of(0, 1), Vec2.of(1, -1));
// SDF for each vertex should be zero.
for (const vertex of testTriangle.vertices) {
expect(testTriangle.signedDistance(vertex)).toBeCloseTo(0);
}
// SDF along each side should be zero
for (const side of testTriangle.getEdges()) {
for (let t = 0.1; t < 1; t += 0.1) {
expect(testTriangle.signedDistance(side.at(t))).toBeCloseTo(0);
}
}
});
it(
'signed distance function should be the negative distance to the edge ' +
'of the triangle on the interior of a shape, same as distance outside of shape',
() => {
const testTriangle = Triangle.fromVertices(Vec2.of(-1, -1), Vec2.of(0, 1), Vec2.of(1, -1));
// A point vertically above the triangle: Outside, so positive SDF
expect(testTriangle.signedDistance(Vec2.of(0, 2))).toBeCloseTo(1);
// Similarly, a point vertically below the triangle is outside, so should have positive SDF
expect(testTriangle.signedDistance(Vec2.of(0, -2))).toBeCloseTo(1);
// A point just above the left side (and outside the triangle) should also have positive SDF
expect(testTriangle.signedDistance(Vec2.of(-0.8, 0.8))).toBeGreaterThan(0);
const firstSide = testTriangle.getEdges()[0];
const firstSideMidpoint = firstSide.at(0.5);
const firstSideNormal = firstSide.direction.orthog();
// Move a point towards the first side
for (let t = 0.5; t > -0.5; t -= 0.1) {
const point = firstSideMidpoint.minus(firstSideNormal.times(t));
const distFromSide1 = firstSide.distance(point);
const signedDist = testTriangle.signedDistance(point);
// Inside the shape
if (t > 0) {
// Inside the shape
expect(testTriangle.containsPoint(point)).toBe(true);
expect(signedDist).toBeCloseTo(-distFromSide1);
} else {
// Outside the shape
expect(testTriangle.containsPoint(point)).toBe(false);
expect(signedDist).toBeCloseTo(distFromSide1);
}
}
},
);
});
});