【算法分析】QQ“一键退朝”之详细计算方法

Tips:由于简书好像不支持Latex公式,所以为了效果,有关公式部分截取了我发表在CSDN上的博文,地址:AZZ的博客


相信很多朋友和我一样很喜欢QQ上“一键退朝”的功能,就是把红点从它原本的地方拉走,消息提醒也就没有了。

一键退朝功能示意图

直到如今我还是觉得这个功能很酷炫!于是想自己实现一番,经过一番调查知道拉伸其实就是由两个圆加上两条贝塞尔曲线组成的形状。

来看看腾讯设计师是怎么设计出来的吧:《QQ手机版 5.0“一键下班”设计小结》

看完了这个对实现思路有很大的帮助,可是我还是不能知道具体是怎么计算实现的,网上大部分的教程都是假想成了两个同样大小的圆来计算,这太取巧了!因为同样大小的圆两条外公切线是平行的,同一个圆上的公切点相连是会垂直于连心线的,但是大小不同的圆并没有这个特殊性!

另外网上也有很多仿照的项目,可是看算法看得头都大了也不明白为什么是这样算的!经过两天的研究,把初中数学(圆、三角函数等相关知识)好好复习了一遍,终于搞清楚了其中算法,现在跟我一起来看看吧!


1.得到连心线


通过观察可以发现,在“一键退朝”这个功能当中,有一个小圆固定在原来坐标位置不动的,只是半径会发生变化,另一个大圆是跟随着我们手指滑动到屏幕的位置来确定圆心坐标的,一般大圆的半径是固定的。

建立两圆的相对坐标系:

PS:在移动端的坐标系 y 轴是向下的。

假设某一个时刻,两圆的状态如图,我们现在可以确定的是小圆的圆心坐标 O 为(startX, startY),大圆的圆心坐标 P0 为 (x0, y0),以及小圆的半径 r 和大圆的半径 R 。

那么首先可以把连心线求出来!也就是 O P0 的距离。


2.求切点坐标

复习一下初中数学:

两个外离的圆,一定有两条外公切线。若两圆半径相同,则两外公切线平行;否则相交于一点,且该点与两圆心在同一直线。

我们再作一张有公切线的图:

切点为 P1、P2、P3、P4,我们现在目的就要求出这四个点,然后就能够在程序中画出切线。

整个算法最难的地方恐怕就是求这四个点了,我们需要借助作图来帮助计算,这之前还需要先复习下定理:

圆心和切点的连线一定垂直于过该点的公切线

再作几个辅助点 A、B、C、D,AB 表示以大圆圆心为原点的坐标系的 x 轴的两端,CD 表示以小圆圆心为原点的坐标系的 x 轴的两端,

3.求剩下两个切点的坐标

一开始我以为 P3、P4 的算法和 P1、P2 一样,就是把上面的减号换成加号就可以了。可是后来验证后发现不对, P3、P4 不能直接使用 β 进行运算。

 为了能愉快阅读,再来复习一下各种拉丁希腊符号叫法:

 α 阿尔法 β 贝塔 γ 伽玛 δ 德尔塔 ε 伊普西隆 ζ 泽塔

如上图作辅助线。

4.画贝塞尔曲线


把四个切点坐标求出来了,后面就简单了,现在就是以切线为原轴,画贝塞尔曲线了,不过我们还缺少一个控制点的坐标。

4.1 科普贝塞尔


怕有不清楚贝塞尔曲线的朋友,我科普一下先,简单来说就是求一段平滑曲线的公式。

如果我们把画一条直线分为进度100%的话,那么当进度为0%,12%,58%,74%时,画线的状态为(注意红色部分末的黑色端点,灰色部分为路径指示)


那么把所有时刻的黑点连接起来就构成了直线:


这个概念应该比较容易接受,好了继续。

二次贝塞尔曲线(最简单的贝塞尔曲线)的作法首先需要两个点确定一条直线,另外在直线外确定一点(即控制点),然后此时三点会形成三个线段,即下图的P0 P2、P0 P1和 P1 P2$(其实不用关注 P0 P2)

这只是进度为0时候的状态,按照上面概念,当进度 t 从 0 变化到 100 时的某一个时刻,比如 30, 66 ,99,那么各个时刻 P0 P1 和 P1 P2 的状态为

t=30


t=66
t=99

可以发现,在 P0 P1 和 P1 P2 上有一直运动的两个点,我们将这两个点连接起来又形成一段新的线段,而在不同时刻,在这个新线段上同样会有一个运动的点,这个点也遵守 t 的变化。


t=30
t=66
t=99

把所有时刻的黄色点连接起来,就形成了二阶贝塞尔曲线。

还不能理解的可以看下这个视频 - > 《bezier curve原理》- > 只要看就好,听不懂英文的可以把声音关掉。


bezier curve原理

费这么大劲把二阶贝塞尔讲了一遍,我们这里其实也只用到了二阶,高阶我就不讲了,一通百通。

4.2.寻找控制点


那么现在线段已经能确定了,就是两条公切线线段(P1P2、P3P4),那么控制点在哪呢?

这个其实有点靠猜了=。= 一开始我觉得应该在连心线的中点,其实实现后效果也还行,后来参照腾讯设计师的想法效果更好,他令 P1P2 的控制点为 P1P4 的中点,令 P3P4 的控制点为 P2P3 的中点。

软件实现效果对比(上边控制点是连心线的中点,下边是腾讯设计师提出的控制点):


我个人觉得下边效果更好,也不得不佩服TX设计师的聪明才智,让我自己想可能永远也想不到。

至于求 P1P4 和  P2P3 的中点不难吧?连四个坐标点都求出来了,直接算就可以了!

---

源码地址:https://github.com/Xieyupeng520/AZMetaBall(还会不断完善的,求星星^3^)


---

References:

《QQ手机版 5.0“一键下班”设计小结》

《【Android开源项目解析】QQ“一键下班”功能实现解析——学习Path及贝塞尔曲线的基本使用》

[Github - MetaballLoading]

本教程为了方便讲解有篡改原图,还望原图作者见谅!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容