给定一个圆心为(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
给定一个圆心为(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
当前回答
我稍微修改了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>
其他回答
我想评论@Ahtenus的回答,特别是Ray Hulha的评论,他说代码依赖没有显示出任何弧度,但我的声誉不够高。
这个代码依赖不工作的原因是它的html有一个描边宽度为零的错误。
我修复了它,并在这里添加了第二个示例:http://codepen.io/AnotherLinuxUser/pen/QEJmkN。
html:
<svg>
<path id="theSvgArc"/>
<path id="theSvgArc2"/>
</svg>
相关CSS:
svg {
width : 500px;
height : 500px;
}
path {
stroke-width : 5;
stroke : lime;
fill : #151515;
}
javascript:
document.getElementById("theSvgArc").setAttribute("d", describeArc(150, 150, 100, 0, 180));
document.getElementById("theSvgArc2").setAttribute("d", describeArc(300, 150, 100, 45, 190));
对于寻求答案的人(我也是),如果不是必须使用arc,绘制部分圆的一个更简单的解决方案是使用SVG的stroke-dasharray <circle>。
将虚线数组分为两个元素,并将其范围缩放到所需的角度。起始角度可以使用冲程-达霍夫集进行调整。
看不见一个余弦。
完整的例子和解释: https://codepen.io/mjurczyk/pen/wvBKOvP
由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
一个图像和一些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))
你可以在我写的这篇文章中有更详细的解释。
@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>