一千個圓零一個姑娘http://www.withparadox2.com/archives/90#comments
我參考Hanson在1960年發表的一篇論文(點擊這里查看)做了這個動畫。如果你看過我之前的一篇名為《圖片迷宮》的文章,便不會對下面這位女同學感到陌生。與上次不一樣,這一次我先征得了她的同意方才對照片進行了大刀闊斧的處理,由于手藝不好,勾勒出的人物效果也不盡人意,在此對她表達深深的歉意。
這個動畫實際是一套行星圓系統,設想太陽不動,地球繞著太陽轉,月球繞著地球轉,XX繞著月球轉……圓越多,得出的形狀也就越復雜。Hanson在論文中論證了,如果給出的圓足夠多,理論上是可以得出任何形狀的軌跡線。下面簡要介紹一下基本的制作步驟。
1,處理圖片首先需要勾勒出線條圖,最好能夠一筆從頭畫到尾。但在這個圖里,由于人物的眉毛、嘴巴的存在,沒辦法一筆畫出來,我采取的辦法是加上輔助線,最后作圖時將輔助線抹掉。


然后通過下面這段代碼將上面的位圖轉化為坐標,但這里線段的順序是亂的,需要很大的耐心去手動調整。目前沒找到好的方法。
pic = Import["location of your picture"];lcp = ListCurvePathPlot@ Position[ImageData[Thinning@Binarize[ColorNegate@pic]], 1];lines = Cases[lcp[[1, 1, 3]], _Line] /. {x_Real, y_Real} :> {y, -x};2,復數及傅里葉變換下面僅簡單介紹一下與本文有關的知識,更具體的內容參看其他資料。對于平面上的一點,可以用復數z=x+iy 來表示,極坐標形式為z=reiθ 。對于一個以坐標c=x+iy 為圓心,以ρ 為半徑,以T 為周期,以α 為初始角的圓周運動,可用下式表示(其中t代表時間):
z=c+ρei(2πt/T+α) 例如當t=t0 時,點的坐標為:z=c+ρei(2πt0/T+α)=x+iy+ρ?cos(2πt/T+α)+iρ?sin(2πt/T+α)=(x+ρ?cos(2πt/T+α)+i(y+ρ?sin(2πt/T+α))) 若f(t) 表示運動的點的軌跡,那么以此點為圓心做圓周運動的點可以表示為:z=f(t)+ρ1ei(2πt/T1+α1) 對于N個圓,除了第一個圓心是固定點(c=x+iy )外,還剩下N個運動的點(除了N-1個運動的圓心,第N個圓上還有一個運動的點),由上可得出第N個圓上點的軌跡:z=c+∑k=1N?1ρkei(2πt/Tk+αk) 事實上,這已經和復數的離散傅里葉變換有了絕大部分的相似,下面就越來越簡單了。首先,將之前得到的圖片坐標轉化為復數坐標,即:(x,y)→x+iy ,然后對這N個復數進行傅里葉變換,得到X[k] ,然后再用逆變換通過另一種形式得到原來的坐標:x[n]=∑k=0N?1X[k]ej2πkn/N 令n/N=t ,k=1/Tk 。上面ρk 為實數,這里X[k] 為復數,好像不一樣。那是因為X[k] 中既包括了半徑,也包括了初始角,進一步變換可知:x[t]=∑k=0N?1X[k]ej2πt/Tk=X[0]+∑k=1N?1|X[k]|X[k]|X[k]|ej2πt/Tk=X[0]+∑k=1N?1|X[k]|ejαkej2πt/Tk=X[0]+∑k=1N?1|X[k]|ej(2πt/Tk+αk)=X[0]+∑k=1N?1|X[k]|ej(2πt/Tk+αk) 這里的|X[k]| 便是圓的半徑,通過求和得到圓心坐標,當改變t(0?t?1) ,圓心坐標就會得到更新,從而生成連續動畫。在作圖時,可以根據半徑大小排序,將半徑小的作為“筆尖”,并且可以去掉一些半徑太小的圓。
3,一千個圓零一個姑娘【看原址,辣雞CSDN傳不上】

新聞熱點
疑難解答