|
7900 | 7900 | d3.svg.arc = function() { |
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 | | - var r0 = +innerRadius.apply(this, arguments), r1 = +outerRadius.apply(this, arguments), rc = +cornerRadius.apply(this, arguments), rc0, rc1, 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 ? 1 : 0, cr = r0 < r1 ? 0 : 1; |
| 7903 | + var r0 = +innerRadius.apply(this, arguments), r1 = +outerRadius.apply(this, arguments), rc = +cornerRadius.apply(this, arguments), rc0, rc1, 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 | 7904 | if (rc) { |
7905 | 7905 | rc = Math.min(Math.abs(r1 - r0) / 2 - ε, rc); |
7906 | | - rc0 = Math.min(rc, r0, r0 / (1 / Math.sin(Math.abs(a1 - a0 - 2 * p0) / 2) + 1)); |
7907 | | - rc1 = Math.min(rc, r1, r1 / (1 / Math.sin(Math.abs(a1 - a0 - 2 * p1) / 2) + 1)); |
| 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 | 7908 | } |
7909 | 7909 | if (p1) { |
7910 | 7910 | r0 = Math.max(r0, r1 * p1 / Math.sin(da / 2)); |
7911 | | - rc0 = Math.min(rc, r0 / (1 / Math.sin(Math.abs(a1 - a0 - 2 * p0) / 2) + 1)); |
| 7911 | + rc0 = Math.min(rc, r0 / (1 / Math.sin(da / 2 - p0) + 1)); |
7912 | 7912 | p0 = Math.asin((r1 - rc1) / (r0 + rc0) * Math.sin(p1)); |
7913 | | - rc0 = Math.min(rc, r0 / (1 / Math.sin(Math.abs(a1 - a0 - 2 * p0) / 2) + 1)); |
| 7913 | + rc0 = Math.min(rc, r0 / (1 / Math.sin(da / 2 - p0) + 1)); |
7914 | 7914 | } |
7915 | | - return (da >= τε ? r0 ? circleSegment(r1, cw) + circleSegment(r0, 1 - cw) : circleSegment(r1, cw) : "M" + (rc1 ? roundedArcSegment(r1, rc1, a0 + p1, a1 - p1, 0) : arcSegment(r1, a0 + p1, a1 - p1, cw)) + "L" + (r0 ? rc0 ? roundedArcSegment(r0, rc0, a1 - p0, a0 + p0, 1) : arcSegment(r0, a1 - p0, a0 + p0, 1 - cw) : "0,0")) + "Z"; |
| 7915 | + 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"; |
7916 | 7916 | } |
7917 | 7917 | function circleSegment(r1, cw) { |
7918 | 7918 | return "M0," + r1 + "A" + r1 + "," + r1 + " 0 1," + cw + " 0," + -r1 + "A" + r1 + "," + r1 + " 0 1," + cw + " 0," + r1; |
7919 | 7919 | } |
7920 | 7920 | function arcSegment(r1, a0, a1, cw) { |
7921 | 7921 | 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); |
7922 | 7922 | } |
7923 | | - function roundedArcSegment(r1, rc, a0, a1, inner) { |
7924 | | - var c0 = Math.cos(a0), s0 = Math.sin(a0), c1 = Math.cos(a1), s1 = Math.sin(a1), ra = (inner ? -1 : 1) * rc, ro = Math.sqrt((r1 - ra) * (r1 - ra) - ra * ra), xt0 = ro * c0, yt0 = ro * s0, xt1 = ro * c1, yt1 = ro * s1; |
7925 | | - if (a1 < a0 ^ inner) { |
7926 | | - var 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); |
7927 | | - } else { |
7928 | | - var xt2 = xt0 - ra * s0, yt2 = yt0 + ra * c0, xt3 = xt1 + ra * s1, yt3 = yt1 - ra * c1, ai0 = Math.atan2(yt2, xt2), ai1 = Math.atan2(yt3, xt3); |
7929 | | - } |
| 7923 | + function roundedArcSegment(r1, rc, a0, a1, ccw, cw) { |
| 7924 | + 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); |
7930 | 7925 | if (ai1 < ai0) ai1 += τ; |
7931 | | - var corner = "A" + ra + "," + ra + " 0 0," + (a1 < a0 ^ inner ? "0" : "1") + " "; |
7932 | | - return xt0 + "," + yt0 + corner + d3_svg_arcCircleIntersect(r1, xt2, yt2, ra) + "A" + r1 + "," + r1 + " 0 " + (Math.abs(ai1 - ai0) < π ^ inner ? "0" : "1") + "," + (a1 < a0 ? "0" : "1") + " " + d3_svg_arcCircleIntersect(r1, xt3, yt3, ra) + corner + xt1 + "," + yt1; |
| 7926 | + var corner = "A" + rc + "," + rc + " 0 0," + ccw + " "; |
| 7927 | + 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; |
7933 | 7928 | } |
7934 | 7929 | arc.innerRadius = function(v) { |
7935 | 7930 | if (!arguments.length) return innerRadius; |
|
0 commit comments