给定一个圆心为(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

当前回答

你可以使用我为上面的答案做的JSFiddle代码:

https://jsfiddle.net/tyw6nfee/

你所需要做的就是改变最后一行console.log代码,并给它自己的参数:

  console.log(describeArc(255,255,220,30,180));
  console.log(describeArc(CenterX,CenterY,Radius,startAngle,EndAngle))

其他回答

由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

基于所选答案的ReactJS组件:

import React from 'react';

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

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

const describeSlice = (x, y, radius, startAngle, endAngle) => {

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

    const largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1";

    const d = [
        "M", 0, 0, start.x, start.y,
        "A", radius, radius, 0, largeArcFlag, 0, end.x, end.y
    ].join(" ");

    return d;
};

const path = (degrees = 90, radius = 10) => {
    return describeSlice(0, 0, radius, 0, degrees) + 'Z';
};

export const Arc = (props) => <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300">
    <g transform="translate(150,150)" stroke="#000" strokeWidth="2">
        <path d={path(props.degrees, props.radius)} fill="#333"/>
    </g>

</svg>;

export default Arc;

你可以使用我为上面的答案做的JSFiddle代码:

https://jsfiddle.net/tyw6nfee/

你所需要做的就是改变最后一行console.log代码,并给它自己的参数:

  console.log(describeArc(255,255,220,30,180));
  console.log(describeArc(CenterX,CenterY,Radius,startAngle,EndAngle))

对@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));

一个图像和一些Python

只是为了更好地澄清并提供另一种解决方案。Arc [A]命令使用当前位置作为起点,因此您必须先使用Moveto [M]命令。

那么Arc的参数如下:

rx, ry, x-axis-rotation, large-arc-flag, sweep-flag, xf, yf

如果我们定义下面的svg文件:

<svg viewBox="0 0 500px 500px"> <path fill="red" d=" M 100 100 A 40 40 00 0 180 100 Z " / > < / svg >

你可以用M来设定起点,用参数xf和yf (A)来设定终点。

我们正在寻找圆,所以我们设rx = ry现在基本上它会尝试找到所有半径为rx的圆相交于起点和终点。

import numpy as np

def write_svgarc(xcenter,ycenter,r,startangle,endangle,output='arc.svg'):
    if startangle > endangle: 
        raise ValueError("startangle must be smaller than endangle")
    
    if endangle - startangle < 360:
        large_arc_flag = 0
        radiansconversion = np.pi/180.
        xstartpoint = xcenter + r*np.cos(startangle*radiansconversion)
        ystartpoint = ycenter - r*np.sin(startangle*radiansconversion)
        xendpoint = xcenter + r*np.cos(endangle*radiansconversion)
        yendpoint = ycenter - r*np.sin(endangle*radiansconversion)
        #If we want to plot angles larger than 180 degrees we need this
        if endangle - startangle > 180: large_arc_flag = 1
        with open(output,'a') as f:
            f.write(r"""<path d=" """)
            f.write("M %s %s" %(xstartpoint,ystartpoint))
            f.write("A %s %s 0 %s 0 %s %s" 
                    %(r,r,large_arc_flag,xendpoint,yendpoint))
            f.write("L %s %s" %(xcenter,ycenter))
            f.write(r"""Z"/>""" )
    
    else:
        with open(output,'a') as f:
            f.write(r"""<circle cx="%s" cy="%s" r="%s"/>"""
                    %(xcenter,ycenter,r))

你可以在我写的这篇文章中有更详细的解释。