【算法分析】QQ“一鍵退朝”之詳細(xì)計算方法

Tips:由于簡書好像不支持Latex公式,所以為了效果门粪,有關(guān)公式部分截取了我發(fā)表在CSDN上的博文泪酱,地址:AZZ的博客


相信很多朋友和我一樣很喜歡QQ上“一鍵退朝”的功能,就是把紅點從它原本的地方拉走离赫,消息提醒也就沒有了。

一鍵退朝功能示意圖

直到如今我還是覺得這個功能很酷炫塌碌!于是想自己實現(xiàn)一番渊胸,經(jīng)過一番調(diào)查知道拉伸其實就是由兩個圓加上兩條貝塞爾曲線組成的形狀。

來看看騰訊設(shè)計師是怎么設(shè)計出來的吧:《QQ手機(jī)版 5.0“一鍵下班”設(shè)計小結(jié)》

看完了這個對實現(xiàn)思路有很大的幫助台妆,可是我還是不能知道具體是怎么計算實現(xiàn)的翎猛,網(wǎng)上大部分的教程都是假想成了兩個同樣大小的圓來計算,這太取巧了接剩!因為同樣大小的圓兩條外公切線是平行的切厘,同一個圓上的公切點相連是會垂直于連心線的,但是大小不同的圓并沒有這個特殊性懊缺!

另外網(wǎng)上也有很多仿照的項目疫稿,可是看算法看得頭都大了也不明白為什么是這樣算的!經(jīng)過兩天的研究鹃两,把初中數(shù)學(xué)(圓遗座、三角函數(shù)等相關(guān)知識)好好復(fù)習(xí)了一遍,終于搞清楚了其中算法俊扳,現(xiàn)在跟我一起來看看吧途蒋!


1.得到連心線


通過觀察可以發(fā)現(xiàn),在“一鍵退朝”這個功能當(dāng)中馋记,有一個小圓固定在原來坐標(biāo)位置不動的号坡,只是半徑會發(fā)生變化,另一個大圓是跟隨著我們手指滑動到屏幕的位置來確定圓心坐標(biāo)的梯醒,一般大圓的半徑是固定的宽堆。

建立兩圓的相對坐標(biāo)系:

PS:在移動端的坐標(biāo)系 y 軸是向下的。

假設(shè)某一個時刻茸习,兩圓的狀態(tài)如圖日麸,我們現(xiàn)在可以確定的是小圓的圓心坐標(biāo) O 為(startX, startY),大圓的圓心坐標(biāo) P0 為 (x0, y0)代箭,以及小圓的半徑 r 和大圓的半徑 R 墩划。

那么首先可以把連心線求出來!也就是 O P0 的距離嗡综。


2.求切點坐標(biāo)

復(fù)習(xí)一下初中數(shù)學(xué):

兩個外離的圓乙帮,一定有兩條外公切線。若兩圓半徑相同极景,則兩外公切線平行察净;否則相交于一點,且該點與兩圓心在同一直線盼樟。

我們再作一張有公切線的圖:

切點為 P1氢卡、P2、P3晨缴、P4译秦,我們現(xiàn)在目的就要求出這四個點,然后就能夠在程序中畫出切線击碗。

整個算法最難的地方恐怕就是求這四個點了筑悴,我們需要借助作圖來幫助計算,這之前還需要先復(fù)習(xí)下定理:

圓心和切點的連線一定垂直于過該點的公切線

再作幾個輔助點 A稍途、B阁吝、C、D械拍,AB 表示以大圓圓心為原點的坐標(biāo)系的 x 軸的兩端突勇,CD 表示以小圓圓心為原點的坐標(biāo)系的 x 軸的兩端,

3.求剩下兩個切點的坐標(biāo)

一開始我以為 P3坷虑、P4 的算法和 P1甲馋、P2 一樣,就是把上面的減號換成加號就可以了猖吴。可是后來驗證后發(fā)現(xiàn)不對挥转, P3海蔽、P4 不能直接使用 β 進(jìn)行運算。

?為了能愉快閱讀绑谣,再來復(fù)習(xí)一下各種拉丁希臘符號叫法:

?α 阿爾法 β 貝塔 γ 伽瑪 δ 德爾塔 ε 伊普西隆 ζ 澤塔

如上圖作輔助線党窜。

4.畫貝塞爾曲線


把四個切點坐標(biāo)求出來了,后面就簡單了借宵,現(xiàn)在就是以切線為原軸幌衣,畫貝塞爾曲線了,不過我們還缺少一個控制點的坐標(biāo)。

4.1 科普貝塞爾


怕有不清楚貝塞爾曲線的朋友豁护,我科普一下先哼凯,簡單來說就是求一段平滑曲線的公式。

如果我們把畫一條直線分為進(jìn)度100%的話楚里,那么當(dāng)進(jìn)度為0%断部,12%,58%班缎,74%時蝴光,畫線的狀態(tài)為(注意紅色部分末的黑色端點,灰色部分為路徑指示)


那么把所有時刻的黑點連接起來就構(gòu)成了直線:


這個概念應(yīng)該比較容易接受达址,好了繼續(xù)蔑祟。

二次貝塞爾曲線(最簡單的貝塞爾曲線)的作法首先需要兩個點確定一條直線,另外在直線外確定一點(即控制點)沉唠,然后此時三點會形成三個線段疆虚,即下圖的P0 P2、P0 P1和 P1 P2$(其實不用關(guān)注 P0 P2)

這只是進(jìn)度為0時候的狀態(tài)右冻,按照上面概念装蓬,當(dāng)進(jìn)度 t 從 0 變化到 100 時的某一個時刻,比如 30, 66 ,99纱扭,那么各個時刻 P0 P1 和 P1 P2 的狀態(tài)為

t=30


t=66
t=99

可以發(fā)現(xiàn)牍帚,在 P0 P1 和 P1 P2 上有一直運動的兩個點,我們將這兩個點連接起來又形成一段新的線段乳蛾,而在不同時刻暗赶,在這個新線段上同樣會有一個運動的點,這個點也遵守 t 的變化肃叶。


t=30
t=66
t=99

把所有時刻的黃色點連接起來蹂随,就形成了二階貝塞爾曲線。

還不能理解的可以看下這個視頻 - > 《bezier curve原理》- > 只要看就好因惭,聽不懂英文的可以把聲音關(guān)掉岳锁。


bezier curve原理

費這么大勁把二階貝塞爾講了一遍,我們這里其實也只用到了二階蹦魔,高階我就不講了激率,一通百通。

4.2.尋找控制點


那么現(xiàn)在線段已經(jīng)能確定了勿决,就是兩條公切線線段(P1P2乒躺、P3P4),那么控制點在哪呢低缩?

這個其實有點靠猜了=嘉冒。= 一開始我覺得應(yīng)該在連心線的中點,其實實現(xiàn)后效果也還行,后來參照騰訊設(shè)計師的想法效果更好讳推,他令 P1P2 的控制點為 P1P4 的中點顶籽,令 P3P4 的控制點為 P2P3 的中點。

軟件實現(xiàn)效果對比(上邊控制點是連心線的中點娜遵,下邊是騰訊設(shè)計師提出的控制點):


我個人覺得下邊效果更好蜕衡,也不得不佩服TX設(shè)計師的聰明才智,讓我自己想可能永遠(yuǎn)也想不到设拟。

至于求 P1P4 和? P2P3 的中點不難吧慨仿?連四個坐標(biāo)點都求出來了,直接算就可以了纳胧!

---

源碼地址:https://github.com/Xieyupeng520/AZMetaBall(還會不斷完善的镰吆,求星星^3^)


---

References:

《QQ手機(jī)版 5.0“一鍵下班”設(shè)計小結(jié)》

《【Android開源項目解析】QQ“一鍵下班”功能實現(xiàn)解析——學(xué)習(xí)Path及貝塞爾曲線的基本使用》

[Github - MetaballLoading]

本教程為了方便講解有篡改原圖,還望原圖作者見諒跑慕!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末万皿,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子核行,更是在濱河造成了極大的恐慌牢硅,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芝雪,死亡現(xiàn)場離奇詭異减余,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)惩系,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門位岔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人堡牡,你說我怎么就攤上這事抒抬。” “怎么了晤柄?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵擦剑,是天一觀的道長。 經(jīng)常有香客問我芥颈,道長惠勒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任浇借,我火速辦了婚禮捉撮,結(jié)果婚禮上怕品,老公的妹妹穿的比我還像新娘妇垢。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布闯估。 她就那樣靜靜地躺著灼舍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪涨薪。 梳的紋絲不亂的頭發(fā)上骑素,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機(jī)與錄音刚夺,去河邊找鬼献丑。 笑死,一個胖子當(dāng)著我的面吹牛侠姑,可吹牛的內(nèi)容都是我干的创橄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼莽红,長吁一口氣:“原來是場噩夢啊……” “哼妥畏!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起安吁,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤醉蚁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后鬼店,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體网棍,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年薪韩,在試婚紗的時候發(fā)現(xiàn)自己被綠了确沸。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡俘陷,死狀恐怖罗捎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拉盾,我是刑警寧澤桨菜,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站捉偏,受9級特大地震影響倒得,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜夭禽,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一霞掺、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧讹躯,春花似錦菩彬、人聲如沸缠劝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽惨恭。三九已至,卻和暖如春耙旦,著一層夾襖步出監(jiān)牢的瞬間脱羡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工免都, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留锉罐,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓绕娘,卻偏偏與公主長得像氓鄙,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子业舍,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容