these probably should have been functions all along... or is that too expensive?
changed directional offset computing to be a function instead of pre-computed