1.吃美
从字体的拆分来看,羊大则美。这可能是古人对于美的理解,羊大大的,能让人吃饱,就很美。
2.外在美
随着时代的进步,我们慢慢对美的追求不局限于果腹这一简单需求。举个例子,现在的人对于美的追求更高了,例如不化妆不出门已经是共识。购物时总喜欢对比挑选一个美的。男的喜欢美女,但是哪一种女的算是美女呢?我们生活在这个充满美的世界里,每个人都有自己独特的审美,每个人也都在追求美的路上。但是美没有一个标准,也没有一个规范,它是我们从小到大培养的一种感知。
3.古诗之美
除了我们眼睛看到的美,还有一种美是精神上的美。是我们在学校中润物细无声获得对美的感受。如古诗词之美,看过《庆余年》这部电视剧的同学都知道一个名场面,就是范闲醉酒背诗,听得人热血沸腾的。为什么我们会产生这样的共鸣呢?因为我们和主角一样,接受过九年义务教育,他背的诗句同样我们也背过,我们也懂诗句中的韵律,也明白诗句表达的诗人情感。所以我们能够体会到诗词之美,这是一种精神之美。
4.代码之美
当然,除了古诗之美,我认为写代码也很美,代码美在哪里呢?
对于我来说,C语言这门编程语言本身就很美,首先它很严谨,错一个符号,错一个字符,它就不能运行。所以你就需要一种严谨的态度来应对它。
从代码的书写形式来看,它可以排列的很美。作为一名学习者,需要有良好的书写习惯。在敲代码的时候,用好代码的缩进,空格与空行。使得代码的排列有自己的逻辑和观赏性。
从思维上来说,在敲代码的时候,它可以让你进入一种思考的状态,这个时候你的思维高速运行。如果是一个真正思考着写代码的人一定懂得这种思考的感觉。很多时候,我们可以在这种状态把代码写完,若再过一两天去读这个代码,可能需要花费很长时间才能理解。这个时候就会感叹,我写这个代码时候的脑子真聪明,怎么能够想到这么巧妙的方式的。
一种解决问题后的快感,每个人都是勇者,都勇于去挑战困难。在遇到解决不了的程序问题,往往会绞尽脑汁地去思考。有时候需要我们放松一下自己,去寻找灵感。不管如何,越是难的问题,耗时越长,最终解决后就感觉越满足。这是一种敢于挑战的美,一种思维上的美,是一种境界,一种状态,亦是一种满足!
我不知道大家有没有品读自己写的代码的习惯。反正我喜欢去欣赏自己以前写的代码,去看代码的排版、去反思用过的巧妙的算法、看当初本来要一百行代码写完的东西,被优化后十行就搞定、去看以前需要用二维数组实现的东西,最后缩减到一维数组的,反正就感觉思考的过程很美。
下面分享一个我第一次写的一个TIN三角网的代码,这个代码是我第一次使用Easyx时写的,当初也是思考了很久,打磨了很久。不管如何,现在阅读起来,都能让我产生一种自豪感,代码原来也可以很美。
///////////////////////////////////////////////////
// 程序名称:TIN 三角网生成
// 编译环境:Mictosoft Visual Studio 2013, EasyX_20200315(beta)
// 作 者:luoyh <2864292458@qq.com>
// 最后修改:2020-4-1
// 用于生成 TIN 三角网实现外接圆算法
//
int X[NUMBER]; // 储存 X 方向产生的随机数
int Y[NUMBER]; // 储存 Y 方向产生的随机数
bool LineXY[(1 + NUMBER) * NUMBER / 2] = { false }; // 为了判断两点是否连线定义的一维数组
//判断这两个点是否连线
bool IsLinked(int p1, int p2)
{
if (p1 >= p2)
return LineXY[(1 + p1) * p1 / 2 + p2];
else
return LineXY[(1 + p2) * p2 / 2 + p1];
}
//储存已经绘制过的线
void Link(int p1, int p2)
{
if (p1>=p2)
LineXY[(1 + p1) * p1 / 2 + p2] = true;
else
LineXY[(1 + p2) * p2 / 2 + p1] = true;
}
// 绘制随机点
void drawpoint(int x, int y, float z)
{
float S = 1, L = 0.5;
setfillcolor(HSLtoRGB(z, S, L));
solidcircle(x, y, 4);
}
// 用于计算两点的距离
double distance(double x1, double y1, int x2, int y2)
{
return sqrt((double)((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)));
}
// 用于产生随机点
void Randompoint(int width, int height, int *lx, int *ly, int n)
{
int i;
bool T;
while (true)
{
i = 0;
*lx = (rand() % (width - 60) + 30);
*ly = (rand() % (height - 60) + 30);
while (true)
{
if (i >= n)
{
T = true;
break;
}
if (distance(*lx, *ly, X[i], Y[i]) < 20) // 用于控制随机点之间的距离
{
T = false;
break;
}
i++;
}
if (T == false)
continue;
else
break;
}
}
// 根据三个点坐标算出他们三个形成外接圆的圆心和半径
double CircleCenter(int x1, int y1, int x2, int y2, int x3, int y3, double *x, double *y, double *r)
{
if ((2.0 * (x1 * (y2 - y3) - y1 * (x2 - x3) + x2 * y3 - x3 * y2)) == 0)
{
*x = 0;
*y = 0;
*r = 0;
return *r;
}
*x = ((x1 * x1 + y1 * y1) * (y2 - y3) + (x2 * x2 + y2 * y2) * (y3 - y1) + (x3 * x3 + y3 * y3) * (y1 - y2)) / (2.0 * (x1 * (y2 - y3) - y1 * (x2 - x3) + x2 * y3 - x3 * y2));
*y = ((x1 * x1 + y1 * y1) * (x3 - x2) + (x2 * x2 + y2 * y2) * (x1 - x3) + (x3 * x3 + y3 * y3) * (x2 - x1)) / (2.0 * (x1 * (y2 - y3) - y1 * (x2 - x3) + x2 * y3 - x3 * y2));
*r = sqrt((*x - x1) * (*x - x1) + (*y - y1) * (*y - y1));
return *r;
}
int main()
{
initgraph(WIDTH, HEIGHT);
float G[NUMBER]; // 储存不同的颜色(后期可以用来储存高程
int Z[NUMBER]; // 储存判断过的点的数组
double max = WIDTH * HEIGHT * WIDTH; // 用窗口的长和宽来定义一个相对大的数
int lx; // 储存临时 X 方向产生的变量
int ly; // 储存临时 Y 方向产生的变量
int li; // 用于储存临时判断过的点的下标数
srand((unsigned)time(NULL)); // 初始化随机数
for (int i = 0; i < NUMBER; i++)
{
Randompoint(WIDTH, HEIGHT, &lx, &ly, i);
X[i] = lx; // 产生 X 方向的随机数
Y[i] = ly; // 产生 Y 方向的随机数
G[i] = float(rand() % 240); // 产生不同的颜色的随机数(后期可以用来表示高程)
drawpoint(X[i], Y[i], G[i]); // 绘制随机点
}
float H = 60, S = 1, L = 0.5;
setlinecolor(HSLtoRGB(H, S, L));
// 在随机生成的点中依次判断,找出距离最短的两个点
for (int i = 0; i < NUMBER; i++)
{
for (int j = i+1; j < NUMBER; j++)
{
if (max > distance(X[i], Y[i], X[j], Y[j]))
{
lx = i;
ly = j;
max = distance(X[i], Y[i], X[j], Y[j]);
}
}
}
line(X[lx], Y[lx], X[ly], Y[ly]);
Link(lx, ly);
Z[0] = lx;
Z[1] = ly;
int n = 2;
while (true)
{
if (n >= NUMBER)
break;
int m = 0;
double rad, Xd, Yd, Rd;
bool OK = false;
max = WIDTH * HEIGHT * WIDTH;
// 开始判断随机生成的每一个点
for (int i = 0; i < NUMBER; i++)
{
m = 0;
OK = false;
// 判断这个点是否已经判断过,如果已经判断过,返回判断下一个点,如果不在,继续程序
while (true)
{
if (m >= n)
{
m = 0;
break;
}
if (i == Z[m])
{
OK = true;
break;
}
m++;
}
if (OK == true)
continue;
// 在已经确定的两个点和未确定的点进行计算它们形成三角形的的半径,并判断形成的圆内有无其它的点
// 若无其它的点,则可以连线,如有其它的点,则进行判断下一个点
for (int j = 0; j < n; j++)
{
for (int k = 0; k < n; k++)
{
rad = CircleCenter(X[Z[j]], Y[Z[j]], X[Z[k]], Y[Z[k]], X[i], Y[i], &Xd, &Yd, &Rd);
int cc = 0;
OK = false;
while (true)
{
if (cc >= NUMBER)
break;
// 判断圆内有无其它点,并且这个被判断的点不能为形成这个圆的这个三个点,如果有其它点,就跳出该循环
if (distance(Xd, Yd, X[cc], Y[cc]) <= Rd && cc != Z[k] && cc != Z[j] && cc != i)
{
OK = true;
break;
}
cc++;
}
// 因为圆内有其它点,结束本次循环
if (OK == true)
continue;
if (max >= rad && rad !=0) // 在三个点围成圆内没有点找到半径最小的
{
lx = Z[j];
ly = Z[k];
if (rad >= WIDTH)
continue;
else
{
if (IsLinked(i, lx) == false) // 绘制线段,首先判断这个线段是否已经绘制过
{
Link(i, lx);
line(X[i], Y[i], X[lx], Y[lx]);
/*Sleep(100);*/ // 如果需要查看绘制过程,去掉注释
}
if (IsLinked(i, ly) == false)
{
Link(i, ly);
line(X[i], Y[i], X[ly], Y[ly]);
/*Sleep(100);*/ // 如果需要查看绘制过程,去掉注释
}
if (IsLinked(lx, ly) == false)
{
Link(lx, ly);
line(X[lx], Y[lx], X[ly], Y[ly]);
/*Sleep(100);*/ // 如果需要查看绘制过程,去掉注释
}
li = i;
}
}
}
}
}
Z[n] = li;
n++;
}
//重新描点
for (int i = 0; i < NUMBER; i++)
{
drawpoint(X[i], Y[i], G[i]);
}
_getch();
return 0;
}
运行效果
5.最后一种美
认真做事的态度最美,希望大家都能感受到这种美!