Qt

Moire Pattern

Posted by wyj on March 31, 2019

Moire Pattern

维基百科:

莫列波纹(英语:Moiré pattern),又译为摩尔纹、莫尔条纹、叠纹、水状波纹,是一种在栅栏状条纹重叠下所产生的干涉影像。

具体实现

明眼人一看就知道这非常简单,只要支持一下图片旋转就可以了。我本来只是打算随便写写,温习一下早已生疏的Qt。然而实现的时候却发现困难重重。

首先是我不能自己写图片,因为ppm不支持alpha通道,并且我再也不想手写输出png了。于是使用现成的Qt轮子QPixmap。然而这个QPixmap却不能SetAlphaChannel,因为这个已经被标记为QT_DEPRECATED了,我怎么设置编译选项都不能使他通过编译。同理,google的大多数解决方案都失效了。Qt的documentation嘲讽我:这东西太容易用QPainter实现了,于是干脆把这个功能删掉了。

后来经过反复尝试,我发现QColor的构造函数居然有第四个隐藏的参数。于是可以这么设置图片透明(只在初始化时有效):

QPixmap pix;QPainter p(&pix); //这是我试错试出的QPainter在QPixmap上画图的方法
p.fillRect(pix.rect(),{{255,255,255,0}}); //C++11让这条语句不知所云

这个程序当然需要几个文件中共享全局变量,我采用了一个相比上次的实现更加OO的方法,就是把他们全部写到一个类的public成员中。这比反人类的extern语法正常多了。

我一开始忘了setPen,输出居然一片漆黑,我一直以为是alpha通道的问题。

然后是问题的关键:旋转。首先,手动旋转贼慢,并且有锯齿。这种东西当然不可能自己造轮子了,有两条路走:QPainter的rotate和QMatrix。我惊奇的发现Qt居然自带一个什么操作都有的矩阵类,于是好奇的开始使用QMatrix。然后发现这个多管闲事的QPixMap::transformed()会使图片的alpha通道失效,然而我不会重新设置alpha通道。还好这里只需要画两张图,直接交换一下绘图顺序就可以把透明的画在上面了。

然后发现这个多管闲事的QPainter::drawPixmap()会自动缩放图片,符合目标矩形的形状。我绕了不少弯路,写自闭了。google搜到的结果,无论用直接连接还是梯子都打不开。百度到的结果卵用没有。后来经过无数次的试错和猜测,我大胆的把drawPixmap的第一个参数矩形的坐标调成了负数,大小再调大一些以至于刚好容纳旋转后的图像,这样就不会缩放了。为什么显示还是不正确?原来QRect的构造函数中最后两个参数不是右下角坐标,是长宽。

最后我想让这个角度循环变化,然而我不想再写多线程了,只好键盘操控。

效果很简陋,不放图了。

题外话

刚才看老妈看最强大脑,居然有Robert J. Lang大神和IOIO的介绍。短片里还碰巧看到了我前几天刚折的天马B-3.0。题目是这样的:根据cp图确定一点是否在成品外部。感性理解一下就觉得这很可能等价于确定每条折痕是峰折还是谷折。去过apio2018的都知道,这可以规约到电路可满足性问题,是np完全的。然而robert lang不仅是折纸界无敌大师,还是物理学家和程序员,所以他写了一个软件TreeMaker,可以爆搜出一组合法方案。这个爆搜的效率足以满足日常折纸创作需求。

原来现代折纸已经变得如此大众化了。

然后又看到把平面图不相交绘制的问题,这也太OI了吧。我想起每次调试图论题时打开Graph Editor时先arrange as tree再疯狂调整的情景,真的一模一样。这个参赛选手超级强,是thuwc拿了一等的大佬。