| 296 | } |
| 297 | |
| 298 | func intersectionLineLine(zs Intersections, a0, a1, b0, b1 Point) Intersections { |
| 299 | if a0.Equals(a1) || b0.Equals(b1) { |
| 300 | return zs // zero-length Close |
| 301 | } |
| 302 | |
| 303 | da := a1.Sub(a0) |
| 304 | db := b1.Sub(b0) |
| 305 | anglea := da.Angle() |
| 306 | angleb := db.Angle() |
| 307 | div := da.PerpDot(db) |
| 308 | |
| 309 | // divide by length^2 since otherwise the perpdot between very small segments may be |
| 310 | // below Epsilon |
| 311 | if length := da.Length() * db.Length(); Equal(div/length, 0.0) { |
| 312 | // parallel |
| 313 | if Equal(b0.Sub(a0).PerpDot(db), 0.0) { |
| 314 | // overlap, rotate to x-axis |
| 315 | a := a0.Rot(-anglea, Point{}).X |
| 316 | b := a1.Rot(-anglea, Point{}).X |
| 317 | c := b0.Rot(-anglea, Point{}).X |
| 318 | d := b1.Rot(-anglea, Point{}).X |
| 319 | if Interval(a, c, d) && Interval(b, c, d) { |
| 320 | // a-b in c-d or a-b == c-d |
| 321 | zs = zs.add(a0, 0.0, (a-c)/(d-c), anglea, angleb, true, true) |
| 322 | zs = zs.add(a1, 1.0, (b-c)/(d-c), anglea, angleb, true, true) |
| 323 | } else if Interval(c, a, b) && Interval(d, a, b) { |
| 324 | // c-d in a-b |
| 325 | zs = zs.add(b0, (c-a)/(b-a), 0.0, anglea, angleb, true, true) |
| 326 | zs = zs.add(b1, (d-a)/(b-a), 1.0, anglea, angleb, true, true) |
| 327 | } else if Interval(a, c, d) { |
| 328 | // a in c-d |
| 329 | same := a < d-Epsilon || a < c-Epsilon |
| 330 | zs = zs.add(a0, 0.0, (a-c)/(d-c), anglea, angleb, true, same) |
| 331 | if a < d-Epsilon { |
| 332 | zs = zs.add(b1, (d-a)/(b-a), 1.0, anglea, angleb, true, true) |
| 333 | } else if a < c-Epsilon { |
| 334 | zs = zs.add(b0, (c-a)/(b-a), 0.0, anglea, angleb, true, true) |
| 335 | } |
| 336 | } else if Interval(b, c, d) { |
| 337 | // b in c-d |
| 338 | same := c < b-Epsilon || d < b-Epsilon |
| 339 | if c < b-Epsilon { |
| 340 | zs = zs.add(b0, (c-a)/(b-a), 0.0, anglea, angleb, true, true) |
| 341 | } else if d < b-Epsilon { |
| 342 | zs = zs.add(b1, (d-a)/(b-a), 1.0, anglea, angleb, true, true) |
| 343 | } |
| 344 | zs = zs.add(a1, 1.0, (b-c)/(d-c), anglea, angleb, true, same) |
| 345 | } |
| 346 | } |
| 347 | return zs |
| 348 | } else if a1.Equals(b0) { |
| 349 | // handle common cases with endpoints to avoid numerical issues |
| 350 | zs = zs.add(a1, 1.0, 0.0, anglea, angleb, true, false) |
| 351 | return zs |
| 352 | } else if a0.Equals(b1) { |
| 353 | // handle common cases with endpoints to avoid numerical issues |
| 354 | zs = zs.add(a0, 0.0, 1.0, anglea, angleb, true, false) |
| 355 | return zs |