rubidium@9723: /* $Id$ */ rubidium@9723: rubidium@9723: /** @file direction_func.h Different functions related to conversions between directions. */ rubidium@9723: rubidium@9723: #ifndef DIRECTION_FUNC_H rubidium@9723: #define DIRECTION_FUNC_H rubidium@9723: rubidium@9723: #include "direction_type.h" rubidium@9723: rubidium@9723: /** rubidium@9723: * Return the reverse of a direction rubidium@9723: * rubidium@9723: * @param d The direction to get the reverse from rubidium@9723: * @return The reverse Direction rubidium@9723: */ rubidium@9723: static inline Direction ReverseDir(Direction d) rubidium@9723: { rubidium@9723: return (Direction)(4 ^ d); rubidium@9723: } rubidium@9723: rubidium@9723: rubidium@9723: /** rubidium@9723: * Calculate the difference between to directions rubidium@9723: * rubidium@9723: * @param d0 The first direction as the base rubidium@9723: * @param d1 The second direction as the offset from the base rubidium@9723: * @return The difference how the second directions drifts of the first one. rubidium@9723: */ rubidium@9723: static inline DirDiff DirDifference(Direction d0, Direction d1) rubidium@9723: { rubidium@9723: return (DirDiff)((d0 + 8 - d1) % 8); rubidium@9723: } rubidium@9723: rubidium@9723: /** rubidium@9723: * Applies two differences together rubidium@9723: * rubidium@9723: * This function adds two differences together and return the resulting rubidium@9723: * difference. So adding two DIRDIFF_REVERSE together results in the rubidium@9723: * DIRDIFF_SAME difference. rubidium@9723: * rubidium@9723: * @param d The first difference rubidium@9723: * @param delta The second difference to add on rubidium@9723: * @return The resulting difference rubidium@9723: */ rubidium@9723: static inline DirDiff ChangeDirDiff(DirDiff d, DirDiff delta) rubidium@9723: { rubidium@9723: return (DirDiff)((d + delta) % 8); rubidium@9723: } rubidium@9723: rubidium@9723: /** rubidium@9723: * Change a direction by a given difference rubidium@9723: * rubidium@9723: * This functions returns a new direction of the given direction rubidium@9723: * which is rotated by the given difference. rubidium@9723: * rubidium@9723: * @param d The direction to get a new direction from rubidium@9723: * @param delta The offset/drift applied to the direction rubidium@9723: * @return The new direction rubidium@9723: */ rubidium@9723: static inline Direction ChangeDir(Direction d, DirDiff delta) rubidium@9723: { rubidium@9723: return (Direction)((d + delta) % 8); rubidium@9723: } rubidium@9723: rubidium@9723: rubidium@9723: /** rubidium@9723: * Returns the reverse direction of the given DiagDirection rubidium@9723: * rubidium@9723: * @param d The DiagDirection to get the reverse from rubidium@9723: * @return The reverse direction rubidium@9723: */ rubidium@9723: static inline DiagDirection ReverseDiagDir(DiagDirection d) rubidium@9723: { rubidium@9723: return (DiagDirection)(2 ^ d); rubidium@9723: } rubidium@9723: rubidium@9723: rubidium@9723: /** rubidium@9723: * Applies a difference on a DiagDirection rubidium@9723: * rubidium@9723: * This function applies a difference on a DiagDirection and returns rubidium@9723: * the new DiagDirection. rubidium@9723: * rubidium@9723: * @param d The DiagDirection rubidium@9723: * @param delta The difference to applie on rubidium@9723: * @return The new direction which was calculated rubidium@9723: */ rubidium@9723: static inline DiagDirection ChangeDiagDir(DiagDirection d, DiagDirDiff delta) rubidium@9723: { rubidium@9723: return (DiagDirection)((d + delta) % 4); rubidium@9723: } rubidium@9723: rubidium@9723: /** rubidium@9723: * Convert a Direction to a DiagDirection. rubidium@9723: * rubidium@9723: * This function can be used to convert the 8-way Direction to rubidium@9723: * the 4-way DiagDirection. If the direction cannot be mapped its rubidium@9723: * "rounded clockwise". So DIR_N becomes DIAGDIR_NE. rubidium@9723: * rubidium@9723: * @param dir The direction to convert rubidium@9723: * @return The resulting DiagDirection, maybe "rounded clockwise". rubidium@9723: */ rubidium@9723: static inline DiagDirection DirToDiagDir(Direction dir) rubidium@9723: { rubidium@9723: return (DiagDirection)(dir >> 1); rubidium@9723: } rubidium@9723: rubidium@9723: /** rubidium@9723: * Convert a DiagDirection to a Direction. rubidium@9723: * rubidium@9723: * This function can be used to convert the 4-way DiagDirection rubidium@9723: * to the 8-way Direction. As 4-way are less than 8-way not all rubidium@9723: * possible directions can be calculated. rubidium@9723: * rubidium@9723: * @param dir The direction to convert rubidium@9723: * @return The resulting Direction rubidium@9723: */ rubidium@9723: static inline Direction DiagDirToDir(DiagDirection dir) rubidium@9723: { rubidium@9723: return (Direction)(dir * 2 + 1); rubidium@9723: } rubidium@9723: rubidium@9723: rubidium@9723: /** rubidium@9723: * Select the other axis as provided. rubidium@9723: * rubidium@9723: * This is basically the not-operator for the axis. rubidium@9723: * rubidium@9723: * @param a The given axis rubidium@9723: * @return The other axis rubidium@9723: */ rubidium@9723: static inline Axis OtherAxis(Axis a) rubidium@9723: { rubidium@9723: return (Axis)(a ^ 1); rubidium@9723: } rubidium@9723: rubidium@9723: rubidium@9723: /** rubidium@9723: * Convert a DiagDirection to the axis. rubidium@9723: * rubidium@9723: * This function returns the axis which belongs to the given rubidium@9723: * DiagDirection. The axis X belongs to the DiagDirection rubidium@9723: * north-east and south-west. rubidium@9723: * rubidium@9723: * @param d The DiagDirection rubidium@9723: * @return The axis which belongs to the direction rubidium@9723: */ rubidium@9723: static inline Axis DiagDirToAxis(DiagDirection d) rubidium@9723: { rubidium@9723: return (Axis)(d & 1); rubidium@9723: } rubidium@9723: rubidium@9723: rubidium@9723: /** rubidium@9723: * Converts an Axis to a DiagDirection rubidium@9723: * rubidium@9723: * This function returns the DiagDirection which rubidium@9723: * belongs to the axis. As 2 directions are mapped to an axis rubidium@9723: * this function returns the one which points to south, rubidium@9723: * either south-west (on X axis) or south-east (on Y axis) rubidium@9723: * rubidium@9723: * @param a The axis rubidium@9723: * @return The direction pointed to south rubidium@9723: */ rubidium@9723: static inline DiagDirection AxisToDiagDir(Axis a) rubidium@9723: { rubidium@9723: return (DiagDirection)(2 - a); rubidium@9723: } rubidium@9723: rubidium@9723: /** rubidium@10355: * Converts an Axis to a Direction rubidium@10355: * rubidium@10355: * This function returns the Direction which rubidium@10355: * belongs to the axis. As 2 directions are mapped to an axis rubidium@10355: * this function returns the one which points to south, rubidium@10355: * either south-west (on X axis) or south-east (on Y axis) rubidium@10355: * rubidium@10355: * @param a The axis rubidium@10355: * @return The direction pointed to south rubidium@10355: */ rubidium@10355: static inline Direction AxisToDirection(Axis a) rubidium@10355: { rubidium@10355: return (Direction)(5 - 2 * a); rubidium@10355: } rubidium@10355: rubidium@10355: /** rubidium@9723: * Convert an axis and a flag for north/south into a DiagDirection rubidium@9723: * @param xy axis to convert rubidium@9723: * @param ns north -> 0, south -> 1 rubidium@9723: * @return the desired DiagDirection rubidium@9723: */ rubidium@9723: static inline DiagDirection XYNSToDiagDir(Axis xy, uint ns) rubidium@9723: { rubidium@9723: return (DiagDirection)(xy * 3 ^ ns * 2); rubidium@9723: } rubidium@9723: rubidium@9723: /** rubidium@9723: * Checks if an interger value is a valid DiagDirection rubidium@9723: * rubidium@9723: * @param d The value to check rubidium@9723: * @return True if the value belongs to a DiagDirection, else false rubidium@9723: */ rubidium@9723: static inline bool IsValidDiagDirection(DiagDirection d) rubidium@9723: { rubidium@9723: return d < DIAGDIR_END; rubidium@9723: } rubidium@9723: rubidium@9723: /** rubidium@9723: * Checks if an integer value is a valid Direction rubidium@9723: * rubidium@9723: * @param d The value to check rubidium@9723: * @return True if the value belongs to a Direction, else false rubidium@9723: */ rubidium@9723: static inline bool IsValidDirection(Direction d) rubidium@9723: { rubidium@9723: return d < DIR_END; rubidium@9723: } rubidium@9723: rubidium@9723: /** rubidium@9723: * Checks if an integer value is a valid Axis rubidium@9723: * rubidium@9723: * @param d The value to check rubidium@9723: * @return True if the value belongs to an Axis, else false rubidium@9723: */ rubidium@9723: static inline bool IsValidAxis(Axis d) rubidium@9723: { rubidium@9723: return d < AXIS_END; rubidium@9723: } rubidium@9723: rubidium@9723: #endif /* DIRECTION_H */