|
7901 | 7901 | var innerRadius = d3_svg_arcInnerRadius, outerRadius = d3_svg_arcOuterRadius, cornerRadius = d3_zero, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle, padAngle = d3_svg_arcPadAngle; |
7902 | 7902 | function arc() { |
7903 | 7903 | var r0 = +innerRadius.apply(this, arguments), r1 = +outerRadius.apply(this, arguments), rc = +cornerRadius.apply(this, arguments), rc0 = 0, rc1 = 0, a0 = startAngle.apply(this, arguments) - halfπ, a1 = endAngle.apply(this, arguments) - halfπ, da = Math.abs(a1 - a0), p1 = (+padAngle.apply(this, arguments) || 0) / 2, p0 = 0, cw = a0 > a1 ? 0 : 1, cr = r0 < r1 ^ cw ? 0 : 1; |
7904 | | - if (rc) { |
7905 | | - rc = Math.min(Math.abs(r1 - r0) / 2 - ε, rc); |
7906 | | - rc0 = Math.min(rc, r0, r0 / (1 / Math.sin(da / 2 - p0) + 1)); |
7907 | | - rc1 = Math.min(rc, r1, r1 / (1 / Math.sin(da / 2 - p1) + 1)); |
7908 | | - } |
7909 | 7904 | if (p1) { |
7910 | | - r0 = Math.max(r0, r1 * p1 / Math.sin(da / 2)); |
7911 | | - rc0 = Math.min(rc, r0 / (1 / Math.sin(da / 2 - p0) + 1)); |
7912 | | - p0 = Math.asin((r1 - rc1) / (r0 + rc0) * Math.sin(p1)); |
7913 | | - rc0 = Math.min(rc, r0 / (1 / Math.sin(da / 2 - p0) + 1)); |
| 7905 | + p0 = d3_asin(r1 / r0 * Math.sin(p1)); |
7914 | 7906 | if (!cw) p0 *= -1, p1 *= -1; |
7915 | 7907 | } |
7916 | | - return (da >= τε ? r0 ? circleSegment(r1, cw) + circleSegment(r0, 1 - cw) : circleSegment(r1, cw) : "M" + (rc1 ? roundedArcSegment(r1, rc1, a0 + p1, a1 - p1, cr, cw) : arcSegment(r1, a0 + p1, a1 - p1, cw)) + "L" + (r0 ? rc0 ? roundedArcSegment(r0, rc0, a1 - p0, a0 + p0, cr, 1 - cw) : arcSegment(r0, a1 - p0, a0 + p0, 1 - cw) : "0,0")) + "Z"; |
| 7908 | + return (da >= τε ? r0 ? circleSegment(r1, cw) + circleSegment(r0, 1 - cw) : circleSegment(r1, cw) : "M" + (rc1 ? roundedArcSegment(r1, rc1, a0 + p1, a1 - p1, cr, cw) : arcSegment(r1, a0 + p1, a1 - p1, cw)) + "L" + (rc0 ? roundedArcSegment(r0, rc0, a1 - p0, a0 + p0, cr, 1 - cw) : arcSegment(r0, a1 - p0, a0 + p0, 1 - cw))) + "Z"; |
| 7909 | + } |
| 7910 | + function sweep(x0, y0, x1, y1) { |
| 7911 | + return (x0 - x1) * y0 - (y0 - y1) * x0 > 0 ? 0 : 1; |
7917 | 7912 | } |
7918 | 7913 | function circleSegment(r1, cw) { |
7919 | 7914 | return "M0," + r1 + "A" + r1 + "," + r1 + " 0 1," + cw + " 0," + -r1 + "A" + r1 + "," + r1 + " 0 1," + cw + " 0," + r1; |
7920 | 7915 | } |
7921 | 7916 | function arcSegment(r1, a0, a1, cw) { |
7922 | | - return r1 * Math.cos(a0) + "," + r1 * Math.sin(a0) + "A" + r1 + "," + r1 + " 0 " + (Math.abs(a1 - a0) < π ? 0 : 1) + "," + cw + " " + r1 * Math.cos(a1) + "," + r1 * Math.sin(a1); |
| 7917 | + var x0 = r1 * Math.cos(a0), y0 = r1 * Math.sin(a0), x1 = r1 * Math.cos(a1), y1 = r1 * Math.sin(a1), df = Math.abs(a1 - a0) <= π ? 0 : 1; |
| 7918 | + if (sweep(x0, y0, x1, y1) === cw ^ df) { |
| 7919 | + var ha = (a0 + a1) / 2; |
| 7920 | + return r1 * Math.cos(ha) + "," + r1 * Math.sin(ha); |
| 7921 | + } |
| 7922 | + return x0 + "," + y0 + "A" + r1 + "," + r1 + " 0 " + df + "," + cw + " " + x1 + "," + y1; |
7923 | 7923 | } |
7924 | | - function roundedArcSegment(r1, rc, a0, a1, ccw, cw) { |
7925 | | - var c0 = Math.cos(a0), s0 = Math.sin(a0), c1 = Math.cos(a1), s1 = Math.sin(a1), ra = cw ? -rc : rc, rb = ccw ? r1 + ra : r1 - ra, ro = Math.sqrt(rb * rb - rc * rc), xt0 = ro * c0, yt0 = ro * s0, xt1 = ro * c1, yt1 = ro * s1, xt2 = xt0 + ra * s0, yt2 = yt0 - ra * c0, xt3 = xt1 - ra * s1, yt3 = yt1 + ra * c1, ai1 = Math.atan2(yt2, xt2), ai0 = Math.atan2(yt3, xt3); |
7926 | | - if (ai1 < ai0) ai1 += τ; |
7927 | | - var corner = "A" + rc + "," + rc + " 0 0," + ccw + " "; |
7928 | | - return xt0 + "," + yt0 + corner + d3_svg_arcCircleIntersect(r1, xt2, yt2, rc) + "A" + r1 + "," + r1 + " 0 " + (Math.abs(ai1 - ai0) > π ^ cw ? 1 : 0) + "," + cw + " " + d3_svg_arcCircleIntersect(r1, xt3, yt3, rc) + corner + xt1 + "," + yt1; |
| 7924 | + function roundedArcSegment(r1, rc, a0, a1, cr, cw) { |
| 7925 | + var c0 = Math.cos(a0), s0 = Math.sin(a0), c1 = Math.cos(a1), s1 = Math.sin(a1), ra = cw ? -rc : rc, rb = cr ? r1 + ra : r1 - ra, ro = Math.sqrt(rb * rb - rc * rc), xt0 = ro * c0, yt0 = ro * s0, xt1 = ro * c1, yt1 = ro * s1, xt2 = xt0 + ra * s0, yt2 = yt0 - ra * c0, xt3 = xt1 - ra * s1, yt3 = yt1 + ra * c1, ai1 = Math.atan2(yt2, xt2), ai0 = Math.atan2(yt3, xt3), corner = "A" + rc + "," + rc + " 0 0," + cr + " "; |
| 7926 | + if (ai1 < ai0 ^ cw) ai1 += τ; |
| 7927 | + return xt0 + "," + yt0 + corner + d3_svg_arcCircleIntersect(r1, xt2, yt2, rc) + "A" + r1 + "," + r1 + " 0 " + (Math.abs(ai1 - ai0) > π ? 1 : 0) + "," + cw + " " + d3_svg_arcCircleIntersect(r1, xt3, yt3, rc) + corner + xt1 + "," + yt1; |
7929 | 7928 | } |
7930 | 7929 | arc.innerRadius = function(v) { |
7931 | 7930 | if (!arguments.length) return innerRadius; |
|
0 commit comments