| 135 | |
| 136 | template <size_t P = N> |
| 137 | typename std::enable_if<P == 2 && N == P, IntersectResult>::type intersection( |
| 138 | Line const& line2, bool infinite = false) const { |
| 139 | Line l1 = *this; |
| 140 | Line l2 = line2; |
| 141 | // Warning to others, do not make the lines positive, because points of |
| 142 | // intersection for coincidental lines are determined by the first point |
| 143 | // And makePositive() changes the order of points. This causes headaches |
| 144 | // later on |
| 145 | // l1.makePositive(); |
| 146 | // l2.makePositive(); |
| 147 | VectorType a = l1.min(); |
| 148 | VectorType b = l1.max(); |
| 149 | VectorType c = l2.min(); |
| 150 | VectorType d = l2.max(); |
| 151 | |
| 152 | VectorType ab = diff(); |
| 153 | VectorType cd = l2.diff(); |
| 154 | |
| 155 | T denom = ab ^ cd; |
| 156 | T xNumer = (a ^ b) * cd[0] - (c ^ d) * ab[0]; |
| 157 | T yNumer = (a ^ b) * cd[1] - (c ^ d) * ab[1]; |
| 158 | |
| 159 | IntersectResult isect; |
| 160 | if (nearZero(denom)) { // the lines are parallel unless |
| 161 | if (nearZero(xNumer) && nearZero(yNumer)) { // the lines are coincidental |
| 162 | isect.intersects = infinite || (a >= c && a <= d) || (c >= a && c <= b); |
| 163 | if (isect.intersects) { |
| 164 | // returns the minimum intersection point |
| 165 | if (infinite) { |
| 166 | isect.point = VectorType::filled(-std::numeric_limits<T>::max()); |
| 167 | } else { |
| 168 | isect.point = a < c ? c : a; |
| 169 | } |
| 170 | } |
| 171 | if (a < c) { |
| 172 | if (c[0] != a[0]) { |
| 173 | isect.t = (c[0] - a[0]) / ab[0]; |
| 174 | } else { |
| 175 | isect.t = (c[1] - a[1]) / ab[1]; |
| 176 | } |
| 177 | } else if (a > d) { |
| 178 | if (d[0] != a[0]) { |
| 179 | isect.t = (d[0] - a[0]) / ab[0]; |
| 180 | } else { |
| 181 | isect.t = (d[1] - a[1]) / ab[1]; |
| 182 | } |
| 183 | } else { |
| 184 | isect.t = 0; |
| 185 | } |
| 186 | isect.coincides = true; |
| 187 | isect.glances = isect.intersects; |
| 188 | } else { |
| 189 | isect.intersects = false; |
| 190 | isect.t = std::numeric_limits<T>::max(); |
| 191 | isect.point = VectorType(); |
| 192 | isect.coincides = false; |
| 193 | isect.glances = false; |
| 194 | } |