When drawing 90-degree boxes on the tan line, I want the 90-degree box to be facing upwards at angles 0-90 (in Quadrant I) and 180-270 (Quadrant III), and facing down in the other ones Quadrants II and IV).
http://www.emathematics.net/imagenes/cuadrantes.gif
Note: I’m using a nice coords helper function to help make the other code easier to understand too:
const coords = (radians, cosRatio, sinRatio) =>
cosRatio * Math.cos(radians) + sinRatio * Math.sin(radians);
One way to do this is to check if I’m in Quadrant I or III first, which can be done by checking the sign after multiplying sin and cos together. Two pluses multiplied or two negatives multiplied will result in a plus sign:
(Math.sign(Math.cos(radians) * Math.sin(radians)) > 0) // Quadrant I and III, or II and IV
? {
xStart: Math.cos(radians) + conf.boxSize * coords(radians, 1, 0),
yStart: Math.sin(radians) + conf.boxSize * coords(radians, 0, 1),
xEnd: Math.cos(radians) + conf.boxSize * coords(radians, 1, 1),
yEnd: Math.sin(radians) + conf.boxSize * coords(radians, -1, 1),
color: "rgb(0,0,0)"
}
: {
xStart: Math.cos(radians) + conf.boxSize * coords(radians, 1, 0),
yStart: Math.sin(radians) + conf.boxSize * coords(radians, 0, 1),
xEnd: Math.cos(radians) + conf.boxSize * coords(radians, 1, -1),
yEnd: Math.sin(radians) + conf.boxSize * coords(radians, 1, 1),
color: "rgb(0,0,0)"
}
I like that because it’s nice and simple and makes the coords multipliers easy to see, but it’s a significant duplication of code.
An alternative is to use the result of Math.sign directly so that we only have one set of formulas,
{
xStart: Math.cos(radians) + conf.boxSize * coords(radians, 1, 0),
yStart: Math.sin(radians) + conf.boxSize * coords(radians, 0, 1),
xEnd: Math.cos(radians) + conf.boxSize * coords(radians, 1, Math.sign(Math.cos(radians) * Math.sin(radians))),
yEnd: Math.sin(radians) + conf.boxSize * coords(radians, -Math.sign(Math.cos(radians) * Math.sin(radians)), 1),
color: "rgb(0,0,0)"
}
Which is better because it’s just one set of code, but now makes the it more difficult to understand what the code is doing.
Currently this is is a part of one large object, so are there any other alternatives? Oh no, a better alternative might have just sleeted its way through the universe and struck me:
Perhaps I could offload this to a separate function instead?
const tanBoxTop = function (radians) {
var sign = Math.sign(Math.cos(radians) * Math.sin(radians));
return {
xStart: Math.cos(radians) + conf.boxSize * coords(radians, 1, 0),
yStart: Math.sin(radians) + conf.boxSize * coords(radians, 0, 1),
xEnd: Math.cos(radians) + conf.boxSize * coords(radians, 1, sign),
yEnd: Math.sin(radians) + conf.boxSize * coords(radians, -sign, 1),
color: "rgb(0,0,0)"
};
}
Are there better options than this? I’m reminded of a phrase from Uncle Bob, “Extract till you drop”.