gpt4 book ai didi

javascript - SVG donut 切片作为路径元素(环形扇区)

转载 作者:数据小太阳 更新时间:2023-10-29 04:27:11 24 4
gpt4 key购买 nike

好吧,当然,这不是错误,但我对如何通过贝塞尔曲线在点之间获得完美的圆弧感到困惑。

我需要这样的形状:

enter image description here

所以我一直在使用以下公式从中心点、半径和 Angular 计算这样的四个 Angular 点:(x?,y?)=(x+d cos α,y+d sin α),在我的 coffeescript 中看起来像这样:

x1 = centerPointX+outerRadius*Math.cos(currentAngle)
y1 = centerPointY+outerRadius*Math.sin(currentAngle)
x2 = centerPointX+innerRadius*Math.cos(currentAngle)
y2 = centerPointY+innerRadius*Math.sin(currentAngle)
x3 = centerPointX+outerRadius*Math.cos(currentAngle2)
y3 = centerPointY+outerRadius*Math.sin(currentAngle2)
x4 = centerPointX+innerRadius*Math.cos(currentAngle2)
y4 = centerPointY+innerRadius*Math.sin(currentAngle2)

我如何利用我拥有的信息并生成具有完美圆形曲线的路径元素?

(PS 我是 SVG 的新手,如果你想帮助我解决 d= 的正确语法,那会很酷,但我总是可以自己写。我想要帮助的挑战实际上更多用贝塞尔曲线做。

更新/解决方案

在下面的指导下使用答案是我实际使用的功能:

annularSector = (centerX,centerY,startAngle,endAngle,innerRadius,outerRadius) ->               
startAngle = degreesToRadians startAngle+180
endAngle = degreesToRadians endAngle+180
p = [
[ centerX+innerRadius*Math.cos(startAngle), centerY+innerRadius*Math.sin(startAngle) ]
[ centerX+outerRadius*Math.cos(startAngle), centerY+outerRadius*Math.sin(startAngle) ]
[ centerX+outerRadius*Math.cos(endAngle), centerY+outerRadius*Math.sin(endAngle) ]
[ centerX+innerRadius*Math.cos(endAngle), centerY+innerRadius*Math.sin(endAngle) ]
]
angleDiff = endAngle - startAngle
largeArc = (if (angleDiff % (Math.PI * 2)) > Math.PI then 1 else 0)
commands = []

commands.push "M" + p[0].join()
commands.push "L" + p[1].join()
commands.push "A" + [ outerRadius, outerRadius ].join() + " 0 " + largeArc + " 1 " + p[2].join()
commands.push "L" + p[3].join()
commands.push "A" + [ innerRadius, innerRadius ].join() + " 0 " + largeArc + " 0 " + p[0].join()
commands.push "z"

return commands.join(" ")

最佳答案

演示:http://phrogz.net/svg/procedural_annular_sector.xhtml

用法:

annularSector( myPathElement, {
centerX:100, centerY:150,
startDegrees:190, endDegrees:230,
innerRadius:75, outerRadius:100
});

核心功能:

// Options:
// - centerX, centerY: coordinates for the center of the circle
// - startDegrees, endDegrees: fill between these angles, clockwise
// - innerRadius, outerRadius: distance from the center
// - thickness: distance between innerRadius and outerRadius
// You should only specify two out of three of the radii and thickness
function annularSector(path,options){
var opts = optionsWithDefaults(options);
var p = [ // points
[opts.cx + opts.r2*Math.cos(opts.startRadians),
opts.cy + opts.r2*Math.sin(opts.startRadians)],
[opts.cx + opts.r2*Math.cos(opts.closeRadians),
opts.cy + opts.r2*Math.sin(opts.closeRadians)],
[opts.cx + opts.r1*Math.cos(opts.closeRadians),
opts.cy + opts.r1*Math.sin(opts.closeRadians)],
[opts.cx + opts.r1*Math.cos(opts.startRadians),
opts.cy + opts.r1*Math.sin(opts.startRadians)],
];

var angleDiff = opts.closeRadians - opts.startRadians;
var largeArc = (angleDiff % (Math.PI*2)) > Math.PI ? 1 : 0;
var cmds = [];
cmds.push("M"+p[0].join()); // Move to P0
cmds.push("A"+[opts.r2,opts.r2,0,largeArc,1,p[1]].join()); // Arc to P1
cmds.push("L"+p[2].join()); // Line to P2
cmds.push("A"+[opts.r1,opts.r1,0,largeArc,0,p[3]].join()); // Arc to P3
cmds.push("z"); // Close path (Line to P0)
path.setAttribute('d',cmds.join(' '));

function optionsWithDefaults(o){
// Create a new object so that we don't mutate the original
var o2 = {
cx : o.centerX || 0,
cy : o.centerY || 0,
startRadians : (o.startDegrees || 0) * Math.PI/180,
closeRadians : (o.endDegrees || 0) * Math.PI/180,
};

var t = o.thickness!==undefined ? o.thickness : 100;
if (o.innerRadius!==undefined) o2.r1 = o.innerRadius;
else if (o.outerRadius!==undefined) o2.r1 = o.outerRadius - t;
else o2.r1 = 200 - t;
if (o.outerRadius!==undefined) o2.r2 = o.outerRadius;
else o2.r2 = o2.r1 + t;

if (o2.r1<0) o2.r1 = 0;
if (o2.r2<0) o2.r2 = 0;

return o2;
}
}

关于javascript - SVG donut 切片作为路径元素(环形扇区),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11479185/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com