handle line-arc intersections and their peculiarities regarding angles
(zs Intersections, pos Point, dira, dirb, t, t0, t1, angle, theta0, theta1 float64, tangent bool)
| 494 | |
| 495 | // handle line-arc intersections and their peculiarities regarding angles |
| 496 | func addLineArcIntersection(zs Intersections, pos Point, dira, dirb, t, t0, t1, angle, theta0, theta1 float64, tangent bool) Intersections { |
| 497 | if theta0 <= theta1 { |
| 498 | angle = theta0 - Epsilon + angleNorm(angle-theta0+Epsilon) |
| 499 | } else { |
| 500 | angle = theta1 - Epsilon + angleNorm(angle-theta1+Epsilon) |
| 501 | } |
| 502 | endpoint := Equal(t, t0) || Equal(t, t1) || Equal(angle, theta0) || Equal(angle, theta1) |
| 503 | if endpoint { |
| 504 | // deviate angle slightly at endpoint when aligned to properly set Into |
| 505 | if (theta0 <= theta1) == (Equal(angle, theta0) || !Equal(angle, theta1) && Equal(t, t0)) { |
| 506 | dirb += Epsilon * 2.0 // t=0 and CCW, or t=1 and CW |
| 507 | } else { |
| 508 | dirb -= Epsilon * 2.0 // t=0 and CW, or t=1 and CCW |
| 509 | } |
| 510 | dirb = angleNorm(dirb) |
| 511 | } |
| 512 | |
| 513 | // snap segment parameters to 0.0 and 1.0 to avoid numerical issues |
| 514 | var s float64 |
| 515 | if Equal(t, t0) { |
| 516 | t = 0.0 |
| 517 | } else if Equal(t, t1) { |
| 518 | t = 1.0 |
| 519 | } else { |
| 520 | t = (t - t0) / (t1 - t0) |
| 521 | } |
| 522 | if Equal(angle, theta0) { |
| 523 | s = 0.0 |
| 524 | } else if Equal(angle, theta1) { |
| 525 | s = 1.0 |
| 526 | } else { |
| 527 | s = (angle - theta0) / (theta1 - theta0) |
| 528 | } |
| 529 | return zs.add(pos, t, s, dira, dirb, endpoint || tangent, false) |
| 530 | } |
| 531 | |
| 532 | // https://www.geometrictools.com/GTE/Mathematics/IntrLine2Circle2.h |
| 533 | func intersectionLineCircle(zs Intersections, l0, l1, center Point, radius, theta0, theta1 float64) Intersections { |
no test coverage detected