Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Anti-Jitter feature. | 改善画笔的防抖功能。 #371

Closed
wdhwg001 opened this issue Mar 10, 2017 · 10 comments
Closed

Improve Anti-Jitter feature. | 改善画笔的防抖功能。 #371

wdhwg001 opened this issue Mar 10, 2017 · 10 comments

Comments

@wdhwg001
Copy link

default
snipaste_20170310_111305

像这样,当手绘尝试绘制一个弧形时,尽管手没有抖,但最终松开鼠标后生成的线条却抖的厉害。

我不知道目前Snipaste使用的防抖算法,不过或许可以尝试一下Cubic Hermite Spline或者其他Spline算法?

插值问题其实是较为复杂的,Cubic Hermite Spline可能是一个比较好的方案,但也有其他的,或许这里会有一些思路: https://www.zhihu.com/question/53708752/answer/136236819

@wdhwg001
Copy link
Author

wdhwg001 commented Mar 10, 2017

以及又仔细看了一下,问题可能出现在采样上,最终生成的曲线继承了最初画笔的锯齿。

或许,采样精度需要进一步的提升?或者,这个问题仅出现在HiDPI即200% DPI下?

需要进一步的调查。


在松开鼠标前,画笔的锯齿跳变是以2像素为一个单位的,或许这是造成锯齿的原因。

@liulex
Copy link
Member

liulex commented Mar 10, 2017

这只是参数设置的问题。目前使用的参数是使得拟合结果尽可能接近于平滑之前的,确实不太理想,我会在下版本做调整。后续或许可以把这个参数交给用户设置。
谢谢你提供的资料。

@wdhwg001
Copy link
Author

更改QT_AUTO_SCREEN_SCALE_FACTOR使得

dots per inch = 2, device pixel ratio = 1

之后,线条变得平滑了一些,但是效果依旧不够理想,至于dpi=1, dpr=2的状况则更糟糕一些,且劣化的程度高于样本数/2,或许还可以引入一个降噪或是干脆在1/2分辨率下计算,然后bilinear插值到200% DPI?因为变形位置主要发生在锯齿区域。

@liulex
Copy link
Member

liulex commented Mar 10, 2017

Snipaste 使用的路径拟合算法是这个:
http://paperjs.org/examples/path-simplification/
之前设置的 tolerance1.5,你可以玩一下上面的 demo,看 tolerance 设为多少比较合适。
当然平滑效果和采样间隔有关,所以如果是慢慢地画,拟合处理的反而会不平滑些。

在乎这个的用户不多,所以就没必要改算法了,当然有现成可用的就另说了。 🌚

@wdhwg001
Copy link
Author

Cubic Hermite Spline的算法我在UE4里看到过,你或许可以在google上找到不少样例代码,其他的诸如Catmull–Rom的也应该能找到。
snipaste_20170310_182113
上图是:
https://github.com/paperjs/paper.js/blob/develop/src/path/Path.js#L1337
中的链接:
https://www.particleincell.com/2012/bezier-splines/
中的示例demo呈现的,可以看出这个算法其实…并不太对。
以及…基于预测和距离的采样或许会比基于时间的采样更可靠一些,但是这样工作量又大了,根据精力取舍吧。

@liulex
Copy link
Member

liulex commented Mar 10, 2017

你上面给的是 smooth 吧,我用到的是 simplify ……
拟合得更平滑的,比如把当前算法的 tolerance 设大,不可避免地会让线条变形更大,可能反而不是用户所希望的。

我用这个算法,就是因为它提供了 demo 并且效果让我满意,所以除非 有直接能用的并且效果明显更好的,没有必要做改变。

@liulex liulex added the later label Mar 16, 2017
@wdhwg001
Copy link
Author

有更新吗?最近又一次被这个问题困扰了,或许可以:

  • 让用户自己设置平滑程度?
  • 直接在绘制的同时对线条进行抗锯齿,并且所见即所得,不在松开鼠标后进行任何平滑?

@liulex
Copy link
Member

liulex commented Apr 20, 2018

https://docs.snipaste.com/zh-cn/advanced-configs?id=misc

[Misc]
path_simplify_tolerance=0

@wdhwg001
Copy link
Author

感谢。直接关闭平滑后效果好一些,但抗锯齿也随之消失了。

我注意到,在前文中的例子:
http://paperjs.org/examples/path-simplification/
中的平滑算法已经比较显著的优于Snipaste中使用的实现了,在path.simplify(1);时可以获得效果较好的平滑度。

以及,线条的抗锯齿和平滑是否应该分开设置?

@liulex
Copy link
Member

liulex commented May 13, 2018

@wdhwg001 输入不同哦,对于相同的鼠标移动速度,桌面应用能够获得的输入点更密集,你在 paperjs.org 缓慢地移动鼠标才能模拟 Snipaste 获得的输入,这种情况下网站计算的效果并不会更好。

@liulex liulex added the done label Apr 7, 2020
@liulex liulex closed this as completed Apr 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants