I have set of points on the coordinate plane. I need to find the 4 points which form a square with the biggest area.
I'm new in JavaScript so I'd like to get any suggestions about code style, patterns, code idioms, etc. Thank you in advance!
"use strict";
/*
* Point
*/
(function() {
function numbersEqual(a, b) {
return Math.abs(a - b) < Number.EPSILON;
}
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.distance = function(a, b) {
return Math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2);
}
Point.equal = function(a, b) {
return numbersEqual(a.x, b.x) && numbersEqual(a.y, b.y);
}
Point.pointsFormsQuadrangle = function(a, b, c, d) {
if (Point.equal(a, b) || Point.equal(a, c) || Point.equal(a, d))
return false;
if (Point.equal(b, c) || Point.equal(b, d))
return false;
if (Point.equal(c, d))
return false;
const center = new Point((a.x + b.x + c.x + d.x) / 4, (a.y + b.y + c.y + d.y) / 4);
const ac = Point.distance(a, center);
const bc = Point.distance(b, center);
const cc = Point.distance(c, center);
const dc = Point.distance(d, center);
return numbersEqual(ac, bc) && numbersEqual(bc, cc) && numbersEqual(cc, dc);
}
Point.pointsFormsSquare = function(a, b, c, d) {
if (!Point.pointsFormsQuadrangle(a, b, c, d))
return false;
const ab = Point.distance(a, b)
const ac = Point.distance(a, c);
const ad = Point.distance(a, d);
const triangle = [ab, ac, ad].sort((a, b) => a - b);
return numbersEqual(triangle[0], triangle[1]);
}
window.Point = Point;
})();
/*
* Square
*/
(function () {
function Square(a, b, c, d) {
this.a = a;
this.b = b;
this.c = c;
this.d = d;
}
Square.prototype.area = function() {
const findSquareDiagonalLength = (a, b, c, d) => {
const ab = Point.distance(a, b);
const ac = Point.distance(a, c);
const ad = Point.distance(a, d);
return Math.max(ab, ac, ad);
};
const d = findSquareDiagonalLength(this.a, this.b, this.c, this.d);
return d * d / 2;
}
window.Square = Square;
})();
/*
* Solution
*/
function formSquaresFromPoints(points) {
let squares = [];
for (let a = 0; a < points.length; a++)
for (let b = a + 1; b < points.length; b++)
for (let c = b + 1; c < points.length; c++)
for (let d = c + 1; d < points.length; d++)
if (Point.pointsFormsSquare(points[a], points[b], points[c], points[d]))
squares.push(new Square(points[a], points[b], points[c], points[d]));
return squares;
}
function sortSquaresByArea(squares) {
squares.sort((a, b) => {
if (a.area() > b.area())
return 1;
else if (a.area() < b.area())
return -1;
else
return 0;
});
return squares;
}
const POINTS = [
new Point(1, 1),
new Point(1, 3),
new Point(3, 1),
new Point(3, 3),
new Point(1, 6),
new Point(6, 1),
new Point(6, 6),
new Point(1, 9),
new Point(9, 1),
new Point(9, 9),
new Point(4, 5),
new Point(4, 8),
new Point(7, 8),
new Point(7, 5),
new Point(6, 3),
new Point(5, 3),
new Point(5, 1)
];
const sortedSquares = sortSquaresByArea(formSquaresFromPoints(POINTS));
const squareWithBiggestArea = sortedSquares[sortedSquares.length - 1];
console.log(squareWithBiggestArea); // Gives: {(1, 1), (1, 9), (9, 1), (9, 9)}