我有一个像这样的SVG元素:
<ellipse class="solidLine" cx="649.9" cy="341.09" rx="39.49" ry="8.41"/>
我需要找到它的length
,以便我可以设置它dashoffset
的动画,让它被“绘制”。
我使用以下标记完成了这些计算:line
polyline
circle
path
,但现在我需要计算椭圆的长度而我是一点点......卡住了。我做了一些谷歌搜索,似乎无法找到一个Javascript方法来计算椭圆的周长。
有任何帮助吗?到目前为止,这是我的函数格式:
const getEllipseLength = (ellipse) => {
let rx = ellipse.getAttribute('rx');
let ry = ellipse.getAttribute('ry');
let totalLength = //function to calculate ellipse circumference using radius-x (rx) and radius-y (ry) here!
return totalLength;
};
谢谢!
编辑:如果有一种快速的方法可以做到这一点并非100%准确(但关闭),那也没关系。我只需要进入实际圆周的球场,以便做一个平滑的动画。
编辑2:我认为使用this等式会给我一个近似的估计,而无需深入研究Euler的系列恶作剧。将它转换为Javascript并查看它是否有效。< / p>
答案 0 :(得分:2)
好吧,这实际上比我想象的要容易一点.http。
由于我只需要一个近似的长度,我将this方程转换为Javascript并提出了这个:
const getEllipseLength = (ellipse) => {
let rx = parseInt(ellipse.getAttribute('rx'));
let ry = parseInt(ellipse.getAttribute('ry'));
let h = Math.pow((rx-ry), 2) / Math.pow((rx+ry), 2);
let totalLength = (Math.PI * ( rx + ry )) * (1 + ( (3 * h) / ( 10 + Math.sqrt( 4 - (3 * h) )) ));
return totalLength;
};
与rx="39.49"
和ry="8.41"
一起使用时,它给我的值为164.20811705227723
,谷歌告诉我实际周长约为166.79
。也不错,对SVG动画来说也不错。
答案 1 :(得分:1)
有一种解决方法。使用此代码:
<path
d="
M cx cy
m -rx, 0
a rx,ry 0 1,1 (rx * 2),0
a rx,ry 0 1,1 -(rx * 2),0
"
/>
我们可以创建一个类似于椭圆的路径。然后,这只是使用getTotalLength()
的问题。检查演示代码段(我使用其他cx
和cy
只是为了节省一些SVG空间):
var length = document.getElementById("path").getTotalLength();
console.log(length)
&#13;
<svg width="200" height="200">
<path id="path" fill="none" stroke="black" stroke-width="1" d="M 49.9, 41.09 m -39.49, 0 a 39.49,8.41 0 1,0 78.98,0 a 39.49,8.41 0 1,0 -78.98,0"/>
</svg>
&#13;
记录166.82369995117188
,非常接近166.79
(由Google工具计算的周长)。
答案 2 :(得分:0)
请注意,该近似对于圆形椭圆非常有效,并且对于长圆形(具有高a / b比率)会产生明显的误差。
如果您了解第二种情况,请使用迭代Gauss-Kummer approach
A = Pi * (a + b) * (1 + h^2/4 + h^4/64 + h^6/256...)
总结,直到下一个加数h^k/2^m
变得足够小
答案 3 :(得分:0)
这是我对椭圆周长的最佳估计:
e = (a - b) / a
P = (1 - e) * (? * ((?/2) * a + (2-(?/2)) * b)) + (e * 4 * a)
function getEllipseLength (ellipse) {
let a = ellipse.getAttribute('rx');
let b = ellipse.getAttribute('ry');
if (a < b) {
var t = a;
a = b;
b = t;
}
var hpi = Math.PI/2;
var e = (a - b) / a; // e = 0 circle or 1 = line
return (1 - e) * (Math.PI * (hpi*a + (2-hpi)*b)) + (e * 4 * a);
}