| 99 | */ |
| 100 | |
| 101 | inT16 POLY_BLOCK::winding_number(const ICOORD &point) { |
| 102 | inT16 count; //winding count |
| 103 | ICOORD pt; //current point |
| 104 | ICOORD vec; //point to current point |
| 105 | ICOORD vvec; //current point to next point |
| 106 | inT32 cross; //cross product |
| 107 | ICOORDELT_IT it = &vertices; //iterator |
| 108 | |
| 109 | count = 0; |
| 110 | do { |
| 111 | pt = *it.data (); |
| 112 | vec = pt - point; |
| 113 | vvec = *it.data_relative (1) - pt; |
| 114 | //crossing the line |
| 115 | if (vec.y () <= 0 && vec.y () + vvec.y () > 0) { |
| 116 | cross = vec * vvec; //cross product |
| 117 | if (cross > 0) |
| 118 | count++; //crossing right half |
| 119 | else if (cross == 0) |
| 120 | return INTERSECTING; //going through point |
| 121 | } |
| 122 | else if (vec.y () > 0 && vec.y () + vvec.y () <= 0) { |
| 123 | cross = vec * vvec; |
| 124 | if (cross < 0) |
| 125 | count--; //crossing back |
| 126 | else if (cross == 0) |
| 127 | return INTERSECTING; //illegal |
| 128 | } |
| 129 | else if (vec.y () == 0 && vec.x () == 0) |
| 130 | return INTERSECTING; |
| 131 | it.forward (); |
| 132 | } |
| 133 | while (!it.at_first ()); |
| 134 | return count; //winding number |
| 135 | } |
| 136 | |
| 137 | |
| 138 | /// @return true if other is inside this. |