计算apprx。 SVG椭圆长度? (使用Javascript计算apprx。椭圆周长)

时间:2016-10-05 05:37:35

标签: javascript math svg ellipse

我有一个像这样的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>

4 个答案:

答案 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()的问题。检查演示代码段(我使用其他cxcy只是为了节省一些SVG空间):

&#13;
&#13;
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;
&#13;
&#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);
}