The dilemma of choice - duplication of code, or easier to understand code?

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”.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.