绘制数学函数而不渲染伪影

Plotting mathematical functions without rendering artefacts

本文关键字:伪影 函数 绘制      更新时间:2023-09-26

我不认为有一个好的答案,但我想知道是否有更好的方法。

我需要绘制一个数学函数,它在显示器的一端几乎是平的,在另一端几乎是垂直的。圆的左下象限将是一个很好的模型。我可以根据需要自动生成任意多个点。

问题是,如果没有各种各样的人工制品,我就无法做到这一点。

我还没有试过贝齐尔拟合;我认为这不会很接近。我的理解是,Bezier适用于一次性手动构建的漂亮图形,而不是真正的曲线拟合。

这样就留下了多段线。我只能对多段线做两件事——我可以选择线的长度(换句话说,我自动生成的点的数量),我可以禁用抗锯齿(setAttributeNS(null,"形状渲染","清晰的边")。

如果我生成了很多点,那么到处都是锯齿,结果是不可用的。它看起来也很像是在振荡,这使得我似乎错误地计算了函数。抗锯齿没有任何区别,因为它不会跨点边界进行操作。

我唯一的解决方案是画更少的点,这样很明显我画的是线段。它不再光滑,但至少没有锯齿或振荡。我用默认的抗锯齿绘制了这个。

有什么想法吗?

编辑:似乎这个的唯一答案是实际上是贝塞尔曲线拟合。您必须进行预处理以找到所需线段的参数,然后绘制结果。谷歌推出了许多关于Beziers曲线拟合的热门产品。

您有数学函数,因此可以根据需要生成任意多的点。

我认为问题在于,因为您不知道输出分辨率(SVG与设备无关),所以您不知道要生成多少点。否则,您可以创建一条多段线,每条线大约有1个像素长。

将数学函数拟合到贝塞尔曲线(可能)不会得到完美匹配——就像三次贝塞尔曲线无法完美匹配圆一样。我认为将函数拟合到贝塞尔曲线的任务不会是微不足道的(我从来没有这样做过)。

你能把你的数学函数输出到画布元素吗?然后,您可以编写一些javascript代码,根据输出分辨率绘制数学函数。类似于图形系统渲染贝塞尔曲线的方式。

你知道图形系统是如何渲染贝塞尔曲线的吗?他们用多段线近似贝塞尔曲线,然后测量多段线和贝塞尔曲线之间的误差差。如果差值大于某个公差-,其中公差由输出分辨率确定-则细分贝塞尔曲线,并对每个贝塞尔曲线重复该过程。当边框和多段线之间的差低于公差时,将绘制多段线。http://en.wikipedia.org/wiki/B%C3%A9zier_curve#Computer_graphics

我想你想在某个区间[a,b]上画y=f(x)

一个经典的解决方案是取均匀分布在[A,b]上的N个点,在这些点上计算f并绘制线(或多项式)。

它当然不适用于你的情况,因为y在某些区域几乎是垂直的。但是,为什么不在这些区域取更多的点(在函数几乎是水平的地方取更少的点)?

你可以计算函数的导数(或者用(f(x+h)-f(x))/h和h小来近似这个导数),并用这个导数确定两个连续点之间的步长