Refactoring the code above gives a cleaned up form which also highlights the simple fact that each corner is basically center + height/2 + width/2, with signs as appropriate for each corner. This also holds if you treat height/2 and width/2 as rotated vectors.
Trusting the interpreter to inline the helpers, this should be pretty effective, should we try to benchmark this.
function addPoints(p1, p2) {
return { x: p1.x + p2.x, y: p1.y + p2.y }
}
function subPoints(p1, p2 ) {
return { x: p1.x - p2.x, y: p1.y - p2.y }
}
function multPoints(p1, p2 ) {
return { x: p1.x * p2.x, y: p1.y * p2.y }
}
function getRulerCorners() {
const sin = Math.sin(ruler.angle);
const cos = Math.cos(ruler.angle);
const height = { x: sin * ruler.height/2, y: cos * ruler.height/2 };
const heightUp = addPoints(ruler, multPoints({x: 1, y :-1}, height));
const heightDown = addPoints(ruler, multPoints({x: -1, y: 1}, height));
const width = { x: cos * ruler.width/2, y: sin * ruler.width/2 };
ruler.nw = subPoints(heightUp, width);
ruler.ne = addPoints(heightUp, width );
ruler.sw = subPoints(heightDown, width);
ruler.se = addPoints(heightDown, width);
}