24 April, 2010

Coding Tricks Using Arithmetic

When I was in 4th semester (if I remember correctly) of computer engineering studies I had a light bulb moment about using simple arithmetic in programming to avoid many if conditions. This was when I looked at my classmate's (who is now my life partner :) ) C program and found out how modulas operator can save me if conditions while implementing a program to convert decimal to binary.

From that day I always try to use arithmetic to avoid conditions. However, many times I forget about this technique and I keep rediscovering this method. So this time I am writing it down here hoping that I remember it and hoping that someone may find it useful.

Problem: I want to pass one axis in a single 1D parameter and later for calculation I need corresponding vector in an array

Solution 1:
One option is to pass "x", "y" or "z" and then use if conditions to find an array form of vector. I have to consider negative axis too so to minimize number of if conditions, I can pass another variable as a multiplier.
proc int[] getVectorOfAxis(string $axis, int $dir)
{
    int $axisVec[3]={0,0,0};
   $axis = tolower($axis);
    if($axis=="x")
        $axisVec = {$dir, 0, 0};
    else if($axis =="y")
        $axisVec = {0, $dir, 0};
    else if($axis == "z")
        $axisVec = {0, 0, $dir};
    return $axisVec;
}

getVectorOfAxis("y", -1);
Solution 2:
However, if we pass integer for axis then we can use arithmetic to find the axis vector without a single if condition.
proc int[] getVectorOfAxis(int $axis)
{
    int $axisVec[3]={0,0,0};
    int $tempInd;
    $tempInd = abs($axis);
    $axisVec[$tempInd-1] =$tempInd/$axis;
    return $axisVec;
}

getVectorOfAxis(-2);
You can argue that the first is easy to understand and it's really not a big deal considering speed is not an issue for us here. However, training mind to use arithmetic can give more flexible options and you can avoid "if" conditions in many cases. I use this trick a lot in making node networks in maya by using multiplyDivide nodes to replace condition nodes.

Solution 3:
If you find passing integers 1,2,3 for axis unintuitive you can still use "x", "y", "z" without conditions. Here is one more solution :)
def getVectorOfAxis(axis, dir):
    axisVec=[0,0,0]
    axisNum = ord(axis.lower())- ord("x")
    axisVec[axisNum] =dir
    return axisVec

getVectorOfAxis("X", -1)

No comments:

Post a Comment