在网上看到好多有奇特图案的函数,比如这个公式
,能绘出
这样的心形图案
。
为了用字符把心形区域填满,只需要设置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;
}
}
未检查汉字完整性,出现边缘乱码情况:
边缘汉字无乱码: