2008年7月19日 星期六

一段愛與極座標系統的故事

被標題騙進來的人....這是數學文章不是愛情故事 XD

前陣子在同學Honda的BBS個版上看到一個關於笛卡兒的故事。其實這個故事源自於網路流傳,出處已經不詳了 (記得很久以前曾經看過不同的版本) ,在這裡引述一下....
十七世紀出生於法國的笛卡兒是第一個發現直角坐標的人,這對後人的貢獻相當大,可惜一生窮困潦倒。
一直到52歲,仍一直默默無名。當時法國正流行黑死病,笛卡兒不得不逃離,流浪到瑞典當乞丐。

某天,他在市場乞討時,有一群少女經過,
其中一名少女發現他的口音不像是瑞典人,她對笛卡兒非常好奇,於是上前問他:

「你從哪來的啊?」

「法國。」

「你是做什麼的啊?」

「我是數學家。」

這名少女叫克麗絲汀,18歲,是位公主,她和其它女孩不同,
克麗絲汀不喜歡文學,而是熱衷數學。
當她聽到笛卡兒說明身份後,感到相當大的興趣,於是把笛卡兒邀請回宮。

笛卡兒就成了她的數學老師,將一生的研究傾囊相授,
而克麗絲汀的數學也日益進步,直角坐標當時也只有笛卡兒這對師生才懂。

後來,他們之間產生了不一樣的情愫,發生喧騰一時的師生戀。
然而這件事傳到國王耳中,讓國王相當憤怒!下令將笛卡兒處死,克麗絲汀以自縊相逼,
國王害怕寶貝女兒真的會想不開,於是...將笛卡兒放逐回法國,也將克麗絲汀軟禁。

笛卡兒一回到法國沒多久就染上黑死病,躺在床上奄奄一息。
笛卡兒不斷地寫信到瑞典給克麗絲汀,都被國王攔截沒收。
克麗絲汀也就不曾收到過笛卡兒寫來的信...

就在笛卡兒快要死去的時候,他寄出了第13封信,當他寄出去沒多久後就氣絕身亡。
這封信的內容只有短短的一行...

r = a(1-sinθ)

國王攔截到這封信後拆開看,發現並不是一如往常的情話。
於是找來城裡所有科學家來研究,但都沒有任何人能夠解開。
國王心想...反正笛卡兒就快要死了,而且公主被軟禁時都悶悶不樂,便把信交給克麗絲汀。

故事暫停一下。




前陣子在PTT程設版看到有人問這樣的問題:
請問版上大大 我現在有一張image(方形)
想把他 warping 成環型(甜甜圈)
網路上沒看到相似的方法
不知道版上的高手有沒有任何想法呢
可以提供給小弟

極座標系統(Polar coordinate system)是解決這個問題的一個快速途徑。下圖 ((圖片引用自維基共享資援)) 是極座標系統的一個範例。



極座標系統定義一個中心點O,並且以與中心點的距離r,以及夾角θ,定位平面上的任何一個點。

極座標系統 (r, θ) 和我們更熟知的直角座標系 (x,y) 間,可以下列公式轉換:

[tex]x = r cos \theta[/tex]
[tex]y = r sin \theta[/tex]
記得這是理組高中數學的內容....

這樣對我們先前提到的問題有什麼幫助呢?

讓我們想想,怎樣在極座標系上,表示半徑為10的圓?
[tex]r = 10[/tex]
怎樣在極座標系上,表示一個內圈半徑為10,外圈半徑為15的環?
[tex]10 < r < 15[/tex]

要怎麼把一個矩型的圖片Wrap(變型)到一個環上,答案就呼之欲出了。


(x,y)為原圖上的座標
(x',y')為目的圖上的座標 (使用直角座標系,x軸向右,y軸向上)
(r,θ)為目的圖上的極標
(w,h)為原圖上的寬及高
R1為環內圈半徑,R2為環的寬度

讓我們觀查一下這組等式:
[tex] r = \frac{y}{h} \times R_{2} + R_{1} [/tex]
[tex] \theta = \frac{x}{w} \times 2\pi [/tex]

第一式讓y值越高時,r越大,距離原點越遠
第二式讓原圖的x座標轉變為目的圖的θ角,達成繞原點一週

但電腦在運算時,最直觀的方法是用點陣圖來處理。
所以我們最好把找到給定(x', y'),找到(x,y)的公式。
因此,將上述等式移項

[tex]x = \theta \times \frac{w}{2\pi} [/tex]
[tex] y = (r-R_{1}) \times \frac{h}{R_{2}} [/tex]

配合

[tex]x' = r cos \theta[/tex]
[tex]y' = r sin \theta[/tex]

便可以(x',y')反查(x,y)

讓我們直接看看實作出來的效果
假設這是原圖(點擊放大) ((這是Gun and roses樂團Paradise City的第一句歌詞)) :



經過上述公式映射後會變成



看起來怪怪的應該是我沒有做Anti-aliasing。我用Matlab實作的程式碼置於文末,取樣時我是用nearest point,有興趣的人可以試著改成bilinear interpolation看看。




回到笛卡兒的故事吧....
當克麗絲汀收到這封信時,雀躍無比,她很高與她的愛人還是想念她。
她立刻動手研究這行字的秘密。沒多久就解出來了,用的就是「直角坐標圖」....

當 θ=0度時,r=a(1-0)=a
θ=90度時,r=a(1-1)=0
θ=180度時,r=a(1-0)=a
θ=270度時,r=a(1+1)=2a,

其中a為四截距的比值,再將所有的點連接起來...就是有名的心臟線

這是網路流傳文章的全文....可是看來他用的是極座標系統,與直角座標系並沒有直接的關係啊。

先不管這個,我們試著把這張圖畫出來吧,使用matlab是很簡單的..
close all; figure;
n = 10000;
a = 10;
X = zeros(n, 1);
Y = zeros(n, 1);
i = 0;
for theta = linspace(0, 2*pi, n+1)
i = i + 1;
r = a * ( 1 - sin(theta) );
X(i) = r * cos(theta);
Y(i) = r * sin(theta);
end
line(X,Y);




原來這張圖代表了笛卡兒對於公主的愛意啊....




至於這個故事的真實性,我想本來就是漏洞百出的,如果有興趣的話,這邊有人考據過了。我想,故事有趣就好,這時候真相可能不是那麼重要吧....XD如果有興趣,可以參考這篇文章

最後,我們可以用上面的方法,把一張矩型的圖片Wrap到一個心型的環上嗎?
原本的等式是
[tex]x = \theta \times \frac{w}{2\pi} [/tex]
[tex] y = (r-R_{1}) \times \frac{h}{R_{2}} [/tex]
我們簡單的以
[tex]R_{1} = a \times ( 1 - sin\theta ) [/tex]
代入即可得到


看起來怪怪的,圖片被太過扭曲了。至於為什麼會這樣,答案就留給有興趣的讀者自己找尋吧...

附上本文所用到的源碼及圖片,很久沒寫Matlab了,很多地方都沒寫好。[Link]

輕省筆電 無責任Survey

之前提到我想買輕省筆電 (我定位為:價位20K以下,重量1.5Kg以下的筆電) 。我針對目前的資訊做了一些調查。我主要是想拿來文書、上網,偶爾寫小程式,調查的方向偏向CPU運算、省電能力優秀的筆電。其實我對於這方面資訊也不甚了解,如果內容有所謬誤歡迎幫忙更正。

2008年7月15日 星期二

Blogger新提供XML匯入匯出功能

Blogger於六月已經開始提供了XML匯入匯出的功能
網路上也有些中文的試用報告,如:Josh's Note: 來試試新玩意之六,Blogger in Draft:Import/Export
這部份我就不多說了。

本站之前提供了一個問題百出的Blog搬家工具 - BlogTrans。
這個工具搬家到Blogger,最大的限制就是每天只能匯入五十篇,以及匯入留言時會有些問題。

Blogger提供的這個新功能,匯出的XML檔基本上是Atom格式,但有的地方必需符合Blogger自己的規格。
一個重要的地方是:這個功能可以匯入留言,也沒有一天五十篇的限制。
所以要是我們摸透了他的XML格式,就有希望利用這個功能,做為將其他Blog資料 (例如無名) 匯入Blogger的方便跳版。

稍微看了一下他的格式,基本上每篇文章的結構是這樣

<entry>
<id>tag:blogger.com,1999:blog-1.post-1</id>
<published>2008-07-14T08:49:00.004-07:00</published>
<updated>2008-07-14T08:56:06.128-07:00</updated>
<category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/blogger/2008/kind#post'/>
<category scheme='http://www.blogger.com/atom/ns#' term='Label2'/><category scheme='http://www.blogger.com/atom/ns#' term='Label1'/>
<title type='text'>Test1</title>
<content type='html'>Test12</content>
<link rel='alternate' type='text/html' href='http://test0012463.blogspot.com/2008/07/test1_9163.html' title='Test1'/>
<link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3196312873051422574/posts/default/3405625350671241273'/>
<author>
<name>大宅鳥</name>
<uri>http://abcde.com</uri>
<email>12345@msn.com</email>
</author>
</entry>

如果要用程式生成這樣的格式,有幾點要注意的:

  • 最重要的一點,id tag似乎只能是tag:blogger.com,1999:blog-12345.post-23456這樣的格式,但裡面的數字不管填什麼,匯入時都沒有問題

  • 已經存在的欄位不要空著。Author裡的name, uri, email其實都沒有作用,但不打的話就會發生錯誤。

  • Comment的部份好像複雜一些,我還沒有摸清他的規則。


目前只研究到這樣。