/**
* @module Triangle
* @fileoverview Contains Triangle class.
*/
/**
* @class
* Triangle used for collision checks.
*/
class Triangle {
/**
* Create a new triangle.
* @param {Vec2} a First point
* @param {Vec2} b Second point
* @param {Vec2} c Third point
* @constructor
*/
constructor(a, b, c) {
this.a = a.copy();
this.b = b.copy();
this.c = c.copy();
}
/**
* Check if this triangle is overlapping with another.
* @param {Triangle} other Triangle to check overlap with
* @returns {Object} Data containing result
*/
check(other) {
const a1 = this.a.copy();
const b1 = this.b.copy();
const c1 = this.c.copy();
const a2 = other.a.copy();
const b2 = other.b.copy();
const c2 = other.c.copy();
const axes = [
a1.normWith(b1),
b1.normWith(c1),
c1.normWith(a1),
a2.normWith(b2),
b2.normWith(c2),
c2.normWith(a2)
];
let minOverlap = Number.POSITIVE_INFINITY;
let maxOverlap = Number.NEGATIVE_INFINITY;
let minOverlapAxis = null;
for (const axis of axes) {
const thisProj = this.project(axis, a1, b1, c1);
const otherProj = other.project(axis, a2, b2, c2);
const overlap = Math.min(thisProj.max, otherProj.max) - Math.max(thisProj.min, otherProj.min);
if (overlap < 0) {
return {
result: false,
other: other,
axes: {x: 0, y: 0}
};
} else if (overlap < minOverlap) {
minOverlap = overlap;
minOverlapAxis = axis;
}
if (overlap > maxOverlap)
maxOverlap = overlap;
}
return {
result: true,
overlap: minOverlap,
maxOverlap: maxOverlap,
axes: minOverlapAxis
};
}
/**
* Projects points onto a specified axis and finds the minimum and maximum projection values.
* @param {Vec2} axis Axis to project onto
* @param {Vec2} a First point
* @param {Vec2} b Second point
* @param {Vec2} c Third point
* @returns {{min: number, max: number}} Object containing minimum and maximum values.
*/
project(axis, a, b, c) {
const points = [a, b, c];
let min = points[0].dot(axis);
let max = min;
for (let i = 1; i < 3; i++) {
const projection = points[i].dot(axis);
min = Math.min(min, projection);
max = Math.max(max, projection);
}
return { min: min, max: max };
}
/**
* Transform a triangle with a transformation matrix.
* @param matrix Transformation matrix
* @returns {Triangle} Transformed version of triangle
*/
transform(matrix) {
return new Triangle(
this.a.transform(matrix),
this.b.transform(matrix),
this.c.transform(matrix)
);
}
/**
* Draw the triangles for debugging.
* @param {CanvasRenderingContext2D} ctx The canvas context to draw on
*/
drawDebug(ctx) {
ctx.strokeStyle = $$.colors.debug_collision;
ctx.lineWidth = 1.5;
ctx.beginPath();
const points = [this.a, this.b, this.c];
for (let i = 0; i < 3; i++) {
const curr = points[i];
const next = points[(i + 1) % 3];
ctx.moveTo(curr.x, curr.y);
ctx.lineTo(next.x, next.y);
ctx.stroke();
}
}
}
export default Triangle;