情人節,用C++畫一個心:)

情人節到啦,作為程序員開發者,應該送給男女朋友什麼禮物呢?我們這次一起用C++語言畫個心作為禮物吧!(被罰跪搓衣板兒什麼的概不負責= =)

在網上稍微查一查心形的曲線方程,會發現很多,最流行的曲線方程應該就是這個了:

嗯,方程看著複雜,我們不管這是怎麼推導出來的(我真的不會啊= =,不過我會一個更丑的心形曲線的推導過程,大家有興趣的話有時間給大家上一堂數學課:)),讓我們使用拿來主義,直接使用吧!我們回憶一下圓的方程,比如: x^{2} + y^{2} = 1 ,那麼所有的點 (x, y) ,若使得 x^{2} + y^{2} = 1 ,則這個點在這個圓的邊界線上;若使得 x^{2} + y^{2} < 1 ,則這個點在圓內;若使得 x^{2} + y^{2} > 1 ,則這個點在圓外。

好了,同理,對於這個方程,若點 (x, y) 讓方程左邊等於0,則這個點在這個心形曲線上;若讓方程左邊小於0,則這個點在這個心形線內;若讓方程左邊大於0,則這個點在這個心形線外。

嗯,我們要做的就是寫一個雙重循環,遍歷x和y的值,將心形線以內的地方,塗上某一個字元,比如『*』。

那麼我們首先要確定我們雙重循環的邊界。我們列印輸出,肯定是要逐行輸出,從上到下。所以我們的第一層循環要對y值做循環。觀察一下,可以看到y的上界大概是1.3;下界大概是-1.1;所以,我們可以從1.3逐漸減少到-1.1,初始我們可以選取步長為0.1。同理,對於x,可以看出他的左右邊界大概為-1.2和+1.2,我們就從-1.2遍歷到1.2,步長也選擇0.1。

我們的第一個代碼就是這樣的:

#include <iostream>n#include <cmath>nusing namespace std;nnint main() {nn for( float y = 1.3 ; y >= -1.1 ; y -= 0.1 ){n for( float x = -1.2 ; x <= 1.2 ; x += 0.1)n if( pow((x*x+y*y-1.0),3) - x*x*y*y*y <= 0.0 )n cout<<*;n elsen cout<< ;n cout<<endl;n }nn return 0;n}n

是不是清晰易懂?運行一下,結果是這樣的:

咦?為什麼這麼瘦?看來x方向要拉伸一下。怎麼拉伸?其實,我們讓我們的步長稍微小一點兒就好了。因為第一層循環(y值)走了多少次,決定了圖像的高度(每走一次,列印一個回車);而第二層循環(x值)走了多少次,則決定了圖像的寬度(每走一次,列印一個字元)。所以,我們把x的步長縮小,x的循環就會多走幾次,相應的,整個圖形就會寬一些。我們將x的步長改為0.05,代碼是這樣的:

#include <iostream>n#include <cmath>nusing namespace std;nnint main() {nn for( float y = 1.3 ; y >= -1.1 ; y -= 0.1 ){n for( float x = -1.2 ; x <= 1.2 ; x += 0.05)n if( pow((x*x+y*y-1.0),3) - x*x*y*y*y <= 0.0 )n cout<<*;n elsen cout<< ;n cout<<endl;n }nn return 0;n}n

結果就變成這樣啦:

是不是好看了許多?

一旦我們掌握了這個技巧,就可以隨易變換我們的這個心形的寬和高啦。比如,我讓這個心形,寬和高更多一些,同時再稍微扁一點兒。y值的步長為0.06,x值的步長為0.025,就是這樣的:

#include <iostream>n#include <cmath>nusing namespace std;nnint main() {nn for( float y = 1.3 ; y >= -1.1 ; y -= 0.06 ){n for( float x = -1.2 ; x <= 1.2 ; x += 0.025)n if( pow((x*x+y*y-1.0),3) - x*x*y*y*y <= 0.0 )n cout<<*;n elsen cout<< ;n cout<<endl;n }nn return 0;n}n

是不是很酷?

當然啦,如果我們填入不同的字元,可能有不同的視覺效果哦~

我們也很容易做出類似的鏤空效果哦~

不過,你以為心形曲線只有一個方程可以描述嗎?在網上多做做功課,發現相關的方程多得很:)比如這個:

我們用同樣的思路,就可以編出這樣的代碼:

#include <iostream>n#include <cmath>nusing namespace std;nnint main() {nn for( float y = 1.3 ; y >= -1.1 ; y -= 0.06 ){n for( float x = -1.1 ; x <= 1.1 ; x += 0.025 )n if( x*x + pow(5.0*y/4.0-sqrt(fabs(x)),2) - 1 <= 0.0 )n cout<<*;n elsen cout<< ;n cout<<endl;n }nn return 0;n}n

得到的心形是這樣的,是不是曲線很不一樣:)

大家可以再在網上多搜索一下,看看有沒有更符合你意的心形曲線:)

熟悉其他語言,尤其是前端語言的同學,也可以利用這些方程,做出更絢麗的效果哦。尤其是使用canvas,大家不妨自己試試看,期待同學們更好的創意:)

願天下有情人終成眷屬,大家加油!

本篇文章的所有代碼可以參見這個github repo: heart-curve-cplusplus

分享一下:有的同學看了這篇帖子以後的創意~ 來自 @甲鐵城的卡巴司機 ,他把自己的日文名字融合在了這個圖案中,超贊啊!


個人原創文章,未經授權,嚴禁轉載,如有違反,必究法律責任。

我的更多文章,歡迎大家關注微信公眾賬號:是不是很酷


推薦閱讀:

「壓」之貪心
成功人士從不刷Leetcode(4)
如何感性地理解EM演算法?
趣說遊戲AI開發:曼哈頓街角的A*演算法
首都機場率先引入阿里雲ET航空大腦,每天調度1700架次航班節省5000個小時

TAG:编程 | CC | 算法 |