【续集】 C语言图形和函数图像的绘制【其他部分 第二章】

           第二章【续集】 图形和函数图像的绘制


  前面我们详细介绍了C语言绘制常见图形和正弦余弦图像的方法,此篇文章为上一篇(http://blog.csdn.net/duanxu_yzc/article/details/12745757,强烈建议:先看上一篇再看续集!!!)的继续,主要有以下内容:

      圆形和抛物线的绘制

      绘制函数图像的第二种方法

      同一坐标系下绘制多个函数图像(交叉图像)


4、圆形和抛物线的绘制

   有了前面绘制三角函数图像的基础,圆形和抛物线的绘制应该非常简单,我们以圆形为例说明:

a、观察需要绘制的图像

【续集】 C语言图形和函数图像的绘制【其他部分 第二章】_第1张图片

      每行需要输出两个点,而且图像左右轴对称

   b、使用的函数:(x-10)2+(y-10)2=102

   c、输出21行,行坐标间距为1

   d、左半圆的列号:10-sqrt(100-(r-10)*(r-10))

      右半圆的列号:10+sqrt(100-(r-10)*(r-10))

   e、调整输出行宽比(因屏幕的行宽比不是一比一,因此不进行调整会导致输出为椭圆)

   按照以上步骤编写代码如下:

  

 C++ Code By DuanXu-yzc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/*
 * 绘制圆形(圆心坐标(10,10),半径为10)
 */

#include <stdio.h>
#include <math.h>

int main (  void )
{
     int rows;
     int r;
     int c;
     float adjust;

    rows =  20;
    adjust =  2. 3;    // 屏幕行宽比(输出屏幕行间距和列间距不同,用adjust作为调整)

     for ( r= 20; r>= 0; r-- )
    {
         // 左半圆
         for ( c= 0; c<adjust*( 10-sqrt( 100-(r- 10)*(r- 10))); c++ )
            printf (  " " );
        printf (  "*" );

         // 右半圆
         for ( ; c<adjust*( 10+sqrt( 100-(r- 10)*(r- 10))); c++ )
            printf (  " " );
        printf (  "*" );

        printf (  "\n" );
    }

     return  0;
}

得到的图像:

【续集】 C语言图形和函数图像的绘制【其他部分 第二章】_第2张图片


抛物线的绘制与圆形极为相似,直接上代码和结果:

/*
 * 绘制抛物线
 */
#include <stdio.h>
#include <math.h>

int main ( void )
{
	int rows;
	int r;
	int c;
	double adjust = 2.3;

	rows = 20;

	for ( r=rows; r>=0; r-- )
	{
		for ( c=0; c<adjust*(10-sqrt(5*r)); c++ )
			printf ( " " );
		printf ( "*" );

		for ( ; c<adjust*(10+sqrt(5*r)); c++ )
			printf ( " " );
		printf ( "*" );

		printf ( "\n" );
	}

	return 0;
}
【续集】 C语言图形和函数图像的绘制【其他部分 第二章】_第3张图片


5、绘制函数图像的第二种方法

    到目前为止,我们使用的方法都是逐行输出,然后通过反函数找到每行需要输出星号的位置,最后通过输出相应个数的空格,确定星号的位置,输出星号。现在介绍另外一种方法,其实与已知的方法很相似,区别在于不需要先输出空格来确定星号的位置,而是逐个判断每行中的各列需要输出的字符是空格还是星号,以圆形为例,每行中,只有列号(调整比例后的)为adjust*(10-sqrt(5*r)和adjust*(10+sqrt(5*r)的位置需要输出星号,其余位置均输出空格。按照这个方法我们重新编写程序如下:

/*
 * 绘制圆形(圆心坐标(10,10),半径为10)的另一种方法
 */

#include <stdio.h>
#include <math.h>

int main ( void )
{
	int rows;
	int r;
	int c;
	int left;
	int right;
	float adjust = 2.3;

	rows = 20;
	for ( r=rows; r>=0; r-- )
	{
		left = adjust*(10-sqrt(100-(r-10)*(r-10)));	// 左半圆的列号(将浮点转化为整型)
		right = adjust*(10+sqrt(100-(r-10)*(r-10)));	// 右半圆的列号(将浮点转化为整型)

		for ( c=0; c<=adjust*20; c++ )
		{
			if ( c == left || c == right )
				printf ( "*" );
			else
				printf ( " " );
		}
		printf ( "\n" );
	}

	return 0;
}
得到图像:
【续集】 C语言图形和函数图像的绘制【其他部分 第二章】_第4张图片

(这个图像与前一种方法绘制的图像有一处明显不同,为什么?请读者思考。)

 

   6、同一坐标系下绘制多个函数图像(交叉图像)

   我们来观察一下直线和圆在同一坐标系下相交的图形:


    同样,这个图像也需要逐行输出,如果按照第一种绘制方法,就需要确定每行中星号的位置,我们发现,图像上半部分的星号依次出现在:左半圆、右半圆、直线,中间部分是:左半圆、直线、右半圆,下半部分是:直线、左半圆、右半圆,这使得我们需要在程序中需要针对不同的行段采取不同的输出顺序,如果图像更复杂的话,这同情况会变得更糟糕。我们再看看第二种绘制方法,这种方法只需要知道哪些地方需要输出星号,并不需要明确的顺序,因此更适合这种交叉图像输出的情况,下面是绘制直线和圆的代码和结果:

/*
 * 同一坐标系下绘制圆形和直线
 */
#include <stdio.h>
#include <math.h>

int main ( void )
{
	int rows = 20;
	int r;
	int c;
	int round_l;
	int round_r;
	int line;

	float adjust = 2.3;

	for ( r=rows; r>=0; r-- )
	{
		round_l = adjust*(10-sqrt(100-(r-10)*(r-10)));
		round_r = adjust*(10+sqrt(100-(r-10)*(r-10)));
		line = adjust*r;

		for ( c=0; c<=adjust*20; c++ )
			if ( ( c == round_l  &&  c == line ) ||
			     ( c == round_r  &&  c == line ) )
				printf ( "+" );			// 交叉的点标记'+'

			else if ( c == round_l  ||  c == round_r )
				printf ( "*" );			// 圆形边界标记'*'

			else if ( c == line )
				printf ( "+" );			// 直线标记'+'

			else
				printf ( " " );			// 其它位置标记空格

		printf ( "\n" );
	}

	return 0;
}
【续集】 C语言图形和函数图像的绘制【其他部分 第二章】_第5张图片

    使用同样的方法绘制余弦和正弦的交叉图像如下:

/*
 * 同一坐标系中绘制余弦和正弦图像
 */
#include <stdio.h>
#include <math.h>

#define PI 3.14

int main ( void )
{
	int rows = 20;
	float r;
	int c;
	int sin_1;
	int sin_2;
	int sin_3;
	int sin_4;
	int cos_1;
	int cos_2;

	float adjust = 10;

	for ( r=1; r>0; r-=0.1 )
	{
		sin_1 = adjust * asin(r);
		sin_2 = adjust * (PI-asin(r));
		cos_1 = adjust * acos(r);
		cos_2 = adjust * (2*PI-acos(r));

		for ( c=0; c<=adjust*2*PI; c++ )
			if ( ( c == sin_1  &&  c == cos_1 )  ||
			     ( c == sin_2  &&  c == cos_1 )  ||
			     ( c == sin_1  &&  c == cos_2 )  ||
			     ( c == sin_2  &&  c == cos_2 ) )
				printf ( "+" );

			else if ( c == sin_1  || c == sin_2 )
				printf ( "*" );

			else if ( c == cos_1  ||  c == cos_2 )
				printf ( "+" );

			else
				printf ( " " );

		printf ( "\n" );
	}

	for ( r=0; r>=-1; r-=0.1 )
	{
		sin_3 = adjust * (PI-asin(r));
		sin_4 = adjust * (2*PI+asin(r));
		cos_1 = adjust * acos(r);
		cos_2 = adjust * (2*PI-acos(r));

		for ( c=0; c<=adjust*2*PI; c++ )
			if ( ( c == sin_3  &&  c == cos_1 )  ||
			     ( c == sin_4  &&  c == cos_1 )  ||
			     ( c == sin_3  &&  c == cos_2 )  ||
			     ( c == sin_4  &&  c == cos_2 ) )
				printf ( "+" );

			else if ( c == sin_3  || c == sin_4 )
				printf ( "*" );

			else if ( c == cos_1  ||  c == cos_2 )
				printf ( "+" );

			else
				printf ( " " );

		printf ( "\n" );
	}

	return 0;
}

【续集】 C语言图形和函数图像的绘制【其他部分 第二章】_第6张图片



 

本章总结

        图形输出是C语言初学者经常遇到的问题,实际上大多数简单的图形并不需要使用复杂的控制结构,所见即所得的方法更加简洁,不过对于复杂的图形或者函数图像,使用控制结构会更好。在使用控制结构输出图形时,要把握一个原则:只能逐行输出,因此,在输出一行时必须把这一行中所有需要输出的字符全部输出,所以,找到每行中各个位置需要输出的字符(或者说,各字符在每行中的位置)尤为关键!我们有两种方法来确定位置,其中第二种方法更通用简洁。在输出图形时,特别是函数图像,要充分利用对称、平移关系简化程序,另外,要注意调节屏幕的行宽比和适当的图像放大,防止图像失真。


声明

    1、此博文版权归断絮所有,如需转载请注明出处http://blog.csdn.net/duanxu_yzc/article/details/12970225,谢谢。

    2、在未经博主断絮允许的情况下,任何个人和机构都不得以任何理由出版此文章,否则必将追究法律责任!


你可能感兴趣的:(编程,c,C语言,图形,TCPL)