给定一个圆心为(200,200),半径为25的圆,如何画出一条从270度到135度的弧以及一条从270度到45度的弧?

0度表示它在x轴上(右侧)(表示它是3点钟位置) 270度表示12点钟位置,90度表示6点钟位置

更一般地说,弧的路径是圆的一部分

x, y, r, d1, d2, direction

意义

center (x,y), radius r, degree_start, degree_end, direction

当前回答

由wdebeaum得到的原始极坐标笛卡尔函数是正确的:

var angleInRadians = angleInDegrees * Math.PI / 180.0;

使用以下方法反转起始点和结束点:

var start = polarToCartesian(x, y, radius, endAngle);
var end = polarToCartesian(x, y, radius, startAngle);

(对我来说)是混乱的,因为这将反转扫旗。使用:

var start = polarToCartesian(x, y, radius, startAngle);
var end = polarToCartesian(x, y, radius, endAngle);

使用sweep-flag = "0"绘制"正常"逆时针弧线, 我认为这更直接。 参见https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths

其他回答

由wdebeaum得到的原始极坐标笛卡尔函数是正确的:

var angleInRadians = angleInDegrees * Math.PI / 180.0;

使用以下方法反转起始点和结束点:

var start = polarToCartesian(x, y, radius, endAngle);
var end = polarToCartesian(x, y, radius, startAngle);

(对我来说)是混乱的,因为这将反转扫旗。使用:

var start = polarToCartesian(x, y, radius, startAngle);
var end = polarToCartesian(x, y, radius, endAngle);

使用sweep-flag = "0"绘制"正常"逆时针弧线, 我认为这更直接。 参见https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths

我稍微修改了opsb的答案,并在圆形扇区的支持填充中进行了修改。 http://codepen.io/anon/pen/AkoGx

JS

function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
  var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;

  return {
    x: centerX + (radius * Math.cos(angleInRadians)),
    y: centerY + (radius * Math.sin(angleInRadians))
  };
}

function describeArc(x, y, radius, startAngle, endAngle){

    var start = polarToCartesian(x, y, radius, endAngle);
    var end = polarToCartesian(x, y, radius, startAngle);

    var arcSweep = endAngle - startAngle <= 180 ? "0" : "1";

    var d = [
        "M", start.x, start.y, 
        "A", radius, radius, 0, arcSweep, 0, end.x, end.y,
        "L", x,y,
        "L", start.x, start.y
    ].join(" ");

    return d;       
}

document.getElementById("arc1").setAttribute("d", describeArc(200, 400, 100, 0, 220));

HTML

<svg>
  <path id="arc1" fill="orange" stroke="#446688" stroke-width="0" />
</svg>

ES6版本:

const angleInRadians = angleInDegrees => (angleInDegrees - 90) * (Math.PI / 180.0);

const polarToCartesian = (centerX, centerY, radius, angleInDegrees) => {
    const a = angleInRadians(angleInDegrees);
    return {
        x: centerX + (radius * Math.cos(a)),
        y: centerY + (radius * Math.sin(a)),
    };
};

const arc = (x, y, radius, startAngle, endAngle) => {
    const fullCircle = endAngle - startAngle === 360;
    const start = polarToCartesian(x, y, radius, endAngle - 0.01);
    const end = polarToCartesian(x, y, radius, startAngle);
    const arcSweep = endAngle - startAngle <= 180 ? '0' : '1';

    const d = [
        'M', start.x, start.y,
        'A', radius, radius, 0, arcSweep, 0, end.x, end.y,
        fullCircle ? 'Z':''
    ].join(' ');

    return d;
};

@opsb的回答很简洁,但中心点不准确,而且,正如@Jithin指出的那样,如果角度是360,那么什么都画不出来。

@Jithin修复了360度的问题,但如果你选择小于360度,那么你会得到一条线关闭弧环,这是不需要的。

我修复了这个问题,并在下面的代码中添加了一些动画:

function myArc(cx, cy, radius, max){ var circle = document.getElementById("arc"); var e = circle.getAttribute("d"); var d = " M "+ (cx + radius) + " " + cy; var angle=0; window.timer = window.setInterval( function() { var radians= angle * (Math.PI / 180); // convert degree to radians var x = cx + Math.cos(radians) * radius; var y = cy + Math.sin(radians) * radius; d += " L "+x + " " + y; circle.setAttribute("d", d) if(angle==max)window.clearInterval(window.timer); angle++; } ,5) } myArc(110, 110, 100, 360); <svg xmlns="http://www.w3.org/2000/svg" style="width:220; height:220;"> <path d="" id="arc" fill="none" stroke="red" stroke-width="2" /> </svg>

对@opsb的回答稍加修改。我们不能用这种方法画一个完整的圆。如果我们给(0,360)它什么也画不出来。所以做了一点小小的修改来解决这个问题。显示有时达到100%的分数可能很有用。

function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
  var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;

  return {
    x: centerX + (radius * Math.cos(angleInRadians)),
    y: centerY + (radius * Math.sin(angleInRadians))
  };
}

function describeArc(x, y, radius, startAngle, endAngle){

    var endAngleOriginal = endAngle;
    if(endAngleOriginal - startAngle === 360){
        endAngle = 359;
    }

    var start = polarToCartesian(x, y, radius, endAngle);
    var end = polarToCartesian(x, y, radius, startAngle);

    var arcSweep = endAngle - startAngle <= 180 ? "0" : "1";

    if(endAngleOriginal - startAngle === 360){
        var d = [
              "M", start.x, start.y, 
              "A", radius, radius, 0, arcSweep, 0, end.x, end.y, "z"
        ].join(" ");
    }
    else{
      var d = [
          "M", start.x, start.y, 
          "A", radius, radius, 0, arcSweep, 0, end.x, end.y
      ].join(" ");
    }

    return d;       
}

document.getElementById("arc1").setAttribute("d", describeArc(120, 120, 100, 0, 359));