1. 程式人生 > >C++用字串組成心形圖案的嘗試

C++用字串組成心形圖案的嘗試

在網上看到好多有奇特圖案的函式,比如這個公式,能繪出這樣的心形圖案

為了用字元把心形區域填滿,只需要設定for迴圈用x和y表示出一個方形畫布區域,如果左邊表示式的值不大於右邊表示式1,則說明座標位於心形區域內,以字元填充之,否則用空格填充區域外的部分。

除此之外,要將字串str中的字元一個一個輸出,問題是漢字佔兩個位元組,英文字母佔一個,在輸出時圖案邊緣常常只輸出漢字的前一個位元組,然後就跑到區域外用空格填充了。這樣就會出現亂碼。因此需要識別字符串中的漢字,在輸出空格前將這個漢字輸出完整。

思路是漢字編碼分兩個位元組,每個位元組都是負值,英文符號佔一個位元組,而且是正值。設定一個變數minus計算待輸出位元組之前連續出現負值的個數,minus計算的思路是:

1.如果待輸出位元組值為正數(minus==0),則待輸出的是一個英文字元,正常輸出即可。

2.如果待輸出的位元組值是漢字的第一個位元組(minus%2==1),不存在之前的漢字沒輸出完的情況,正常輸出即可。

3.其他情況下(minus是偶數,但不是0),則待輸出位元組是漢字的第二個位元組,這個位元組必須把之前的漢字輸出完,不能輸出其他字元,這一步是防止亂碼的關鍵。

繪圖函式draw()如下:

void draw(string str){
	int temp=0;
	int minus=0;
	for(double y=1.3 ; y>=-1.1; y -=0.06){
		for(double x=-1.1 ; x<=1.1 ; x+=0.025){
			if(x*x + pow(5.0*y/4.0 - sqrt(fabs(x)),2) -1 <= 0.0){
				cout << str.at(temp);
				temp = (temp+1)%str.length(); 
			}
			else{
				for(int i=temp;i>=0;i--){
					if( ( (int)str.at(i) ) <0 ) 
						minus++;
					else break;
				}
				if((minus==0)||(minus%2==1)){
					cout << " ";
					minus = 0;
				}
				else{
					cout << str.at(temp);
					temp = (temp+1)%str.length(); 
					minus = 0;
				}
			}
		}
		cout << endl;
	}
}
執行結果:

未檢查漢字完整性,出現邊緣亂碼情況:

邊緣漢字無亂碼: