| 46 | // get x and y distances to take a single pixel step along the whisker |
| 47 | |
| 48 | static void WhiskerStep( |
| 49 | double& xstep, // out: x dist to move one pix along whisker |
| 50 | double& ystep, // out: y dist to move one pix along whisker |
| 51 | const Shape& shape, // in |
| 52 | int ipoint) // in: index of the current point |
| 53 | { |
| 54 | int prev, next; PrevAndNextLandmarks(prev, next, ipoint, shape); |
| 55 | |
| 56 | if ((Equal(shape(prev, IX), shape(ipoint, IX)) && |
| 57 | Equal(shape(prev, IY), shape(ipoint, IY))) || |
| 58 | |
| 59 | (Equal(shape(next, IX), shape(ipoint, IX)) && |
| 60 | Equal(shape(next, IY), shape(ipoint, IY)))) |
| 61 | { |
| 62 | // The prev or next point is on top of the current point. |
| 63 | // Arbitrarily point the whisker in a horizontal direction. |
| 64 | // TODO Revisit, this is common at low resolution pyramid levels. |
| 65 | |
| 66 | xstep = 1; |
| 67 | ystep = 0; |
| 68 | } |
| 69 | else |
| 70 | { |
| 71 | const VEC whisker_direction(Bisector(shape.row(prev), |
| 72 | shape.row(ipoint), |
| 73 | shape.row(next))); |
| 74 | xstep = -whisker_direction(IX); |
| 75 | ystep = -whisker_direction(IY); |
| 76 | |
| 77 | // normalize so either xstep or ystep will be +-1, |
| 78 | // and the other will be smaller than +-1 |
| 79 | |
| 80 | const double abs_xstep = ABS(xstep); |
| 81 | const double abs_ystep = ABS(ystep); |
| 82 | if (abs_xstep >= abs_ystep) |
| 83 | { |
| 84 | xstep /= abs_xstep; |
| 85 | ystep /= abs_xstep; |
| 86 | } |
| 87 | else |
| 88 | { |
| 89 | xstep /= abs_ystep; |
| 90 | ystep /= abs_ystep; |
| 91 | } |
| 92 | } |
| 93 | } |
| 94 | |
| 95 | static inline int Step( // return x coord at the given offset along whisker |
| 96 | double x, // in: x coord of center of whisker |
no test coverage detected