| 17541 | // Compute perpendicular offset line of length rc. |
| 17542 | // http://mathworld.wolfram.com/Circle-LineIntersection.html |
| 17543 | function cornerTangents(x0, y0, x1, y1, r1, rc, cw) { |
| 17544 | var x01 = x0 - x1, |
| 17545 | y01 = y0 - y1, |
| 17546 | lo = (cw ? rc : -rc) / sqrt(x01 * x01 + y01 * y01), |
| 17547 | ox = lo * y01, |
| 17548 | oy = -lo * x01, |
| 17549 | x11 = x0 + ox, |
| 17550 | y11 = y0 + oy, |
| 17551 | x10 = x1 + ox, |
| 17552 | y10 = y1 + oy, |
| 17553 | x00 = (x11 + x10) / 2, |
| 17554 | y00 = (y11 + y10) / 2, |
| 17555 | dx = x10 - x11, |
| 17556 | dy = y10 - y11, |
| 17557 | d2 = dx * dx + dy * dy, |
| 17558 | r = r1 - rc, |
| 17559 | D = x11 * y10 - x10 * y11, |
| 17560 | d = (dy < 0 ? -1 : 1) * sqrt(max(0, r * r * d2 - D * D)), |
| 17561 | cx0 = (D * dy - dx * d) / d2, |
| 17562 | cy0 = (-D * dx - dy * d) / d2, |
| 17563 | cx1 = (D * dy + dx * d) / d2, |
| 17564 | cy1 = (-D * dx + dy * d) / d2, |
| 17565 | dx0 = cx0 - x00, |
| 17566 | dy0 = cy0 - y00, |
| 17567 | dx1 = cx1 - x00, |
| 17568 | dy1 = cy1 - y00; |
| 17569 | |
| 17570 | // Pick the closer of the two intersection points. |
| 17571 | // TODO Is there a faster way to determine which intersection to use? |
| 17572 | if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1; |
| 17573 | |
| 17574 | return { |
| 17575 | cx: cx0, |
| 17576 | cy: cy0, |
| 17577 | x01: -ox, |
| 17578 | y01: -oy, |
| 17579 | x11: cx0 * (r1 / r - 1), |
| 17580 | y11: cy0 * (r1 / r - 1) |
| 17581 | }; |
| 17582 | } |
| 17583 | |
| 17584 | function arc() { |
| 17585 | var innerRadius = arcInnerRadius, |