详细分析如何用C语言输出3D立体感心形图

简介: 详细分析如何用C语言输出3D立体感心形图

详细分析C语言立体感心形图

手码千字,相信你看完之后,会有收获的!

首先我先在每行(除空白以及{}外)代码上标上序号(无序号源码放在了文末)

1.#include <stdio.h>
2.#include <math.h>
3.float f(float x, float y, float z) 
{
4.    float a = x*x + 9.0f/4.0f*y*y + z*z - 1;
5.    return a*a*a - x*x*z*z*z - 9.0f/80.0f*y*y*z*z*z;
}
6.float h(float x, float z) 
{
7.    for (float y = 1.0f; y >= 0.0f; y -= 0.001f)
    {
8.        if (f(x, y, z) <= 0.0f)
9.            return y;
    }
10.    return 0.0f;
}
11.int main() 
{
12.    for (float z = 1.5f; z > -1.5f; z -= 0.1f) 
    {
13.        for (float x = -1.5f; x < 1.5f; x += 0.05f) 
        {
14.            float v = f(x, 0.0f, z);
15.            if (v <= 0.0f) 
            {
16.                float y0 = h(x, z);
17.                float ny = 0.01f;
18.                float nx = h(x + ny, z) - y0;
19.                float nz = h(x, z + ny) - y0;
20.                float nd = 1.0f / sqrtf(nx*nx + ny*ny + nz*nz);
21.                float d = (nx + ny - nz)*nd*0.5f + 0.5f;
22.                putchar(".:-=+*#%@"[(int)(d * 5.0f)]);
            }
23.            else
24.                putchar(' ');
        }
25.        putchar('\n');
    }
26.    return 0;
}

此次空白行以及语句块{}空白花括号就不再多加赘述,简要来说,就是为了整体的完整性与可读性

首先先说一下数值后面加f的问题,例如: y=1.0f 1.0后面的f用于强调前面的1.0是一个float量。 如果不加,默认为double,加了之后,赋值给y时会自动转换为float 的。

逐行分析(除空白以及{}空白行外)

★头文件部分:

1.头文件的定义,可以说是老朋友了,stdio头文件,非常常用的头文件。

2.math头文件,看到math,我们应该会想起数学这个名字,其实没错,math.h头文件定义了各种数学函数和一个宏。此处定义这个头文件的原因就是用到了数学函数sqrtf。


★主函数外自定义函数部分:

3.定义了一个float类型的函数f,有三个float类型的形参x,y,z。

4.定义了一个float类型的变量a,将其赋值为x * x + 9.0f / 4.0f* y * y + z * z - 1;

5.返回一个表达式的值:return a *a * a - x * x * z * z * z - 9.0f/80.0f * y * y * z * z * z;

有关4和5的解释:这其实跟上一次平面心形图方程类型,只不过增加到了第三维度,此处为立体感心形方程:

x * x + 9.0f / 4.0f* y * y + z * z - 1;

return a *a * a - x * x * z * z * z - 9.0f/80.0f * y * y * z * z * z;

6.定义了一个float类型的函数h,有两个float类型的形参x,z。

7.float定义y=1.0f,1.0后面的f用于强调前面的1.0是一个float量。 如果不加,默认为double,加了之后,赋值给y时会自动转换为float 的。

y>=0.0f 判断条件;

z-=0.1f; 也就是z=z-0.1f; 可以类比i-=2; 即 i=i-2;

8.if (f(x, y, z) <= 0.0f)条件判断,调用函数f传参x,y,z看函数返回值是否小于等于0,如果小于,说明y的值就对了,返回y的值到主函数。

9.见8.

10.return返回0.0f表示结束了该函数的执行。


★主函数部分

11.主函数的定义。

12.见7.分析

ps:12和13不再多加阐述,和7道理相同。

13.见7.分析

14.float定义了一个v变量,接收了y=0.0f即y为定值时函数f的返回值。

15.条件判断,看函数返回的v值是否小于等于0,如果小于等于0,则执行语句块内容,输出所设定字符。

16.由15可知,15成立则进入语句16的执行,此处定义变量y0来接收返回值。

17.定义浮点型变量ny,并给它赋值为0.01f。

18.float nx = h(x + ny, z) - y0; 经h函数返回之后相当于,nx=y(x变化)-y0;

19.float nz = h(x, z + ny) - y0; 经h函数返回之后相当于,nz=y(z变化)-y0;

20.float nd = 1.0f / sqrtf(nx * nx + ny * ny + nz * nz); 这里的nd的值就相当于(x * x+y * y+z * z)开方再取倒数。

21.float d = (nx + ny - nz) * nd * 0.5f + 0.5f; d值相当于 d=(x+y-z)*1.0f/sqrtf(x * x+y * y+z * z)+0.5f。

22.putchar(".:-=+*#%@"[(int)(d * 5.0f)]); 输出所设定字符,更好地呈现出立体感心形。

关于17——22这些都是为了更好的呈现立体感图形所写,关联到输出的位置,输出的形状等多个方面,可以说,是立体感心形代码中核心代码之一(而且是很关键的)。

23.if else中else否则部分;

24.如果执行else语句,则输出空白;

25.输出换行;

26.return 0; return语句结束main()函数的执行,把0返还给操作系统。


无序号源码:

#include <stdio.h>
#include <math.h>
float f(float x, float y, float z) 
{
    float a = x*x + 9.0f/4.0f*y*y + z*z - 1;
    return a*a*a - x*x*z*z*z - 9.0f/80.0f*y*y*z*z*z;
}
float h(float x, float z) 
{
    for (float y = 1.0f; y >= 0.0f; y -= 0.001f)
    {
        if (f(x, y, z) <= 0.0f)
            return y;
    }
    return 0.0f;
}
int main() 
{
    for (float z = 1.5f; z > -1.5f; z -= 0.1f) 
    {
        for (float x = -1.5f; x < 1.5f; x += 0.05f) 
        {
            float v = f(x, 0.0f, z);
            if (v <= 0.0f) 
            {
                float y0 = h(x, z);
                float ny = 0.01f;
                float nx = h(x + ny, z) - y0;
                float nz = h(x, z + ny) - y0;
                float nd = 1.0f / sqrtf(nx*nx + ny*ny + nz*nz);
                float d = (nx + ny - nz)*nd*0.5f + 0.5f;
                putchar(".:-=+*#%@"[(int)(d * 5.0f)]);
            }
            else
                putchar(' ');
        }
        putchar('\n');
    }
}


希望这篇文章对你有所帮助!

作者Code_流苏(一个喜欢古诗词和编程的Coder😊)

创作不易,喜欢的话,还请多多点赞与关注!ღ( ´・ᴗ・` )比心!

感谢支持!欢迎评论交流学习!

如果有误,还请指出!可能个人解释的不是很好,如果有更好的见解,欢迎评论交流,一起学习!


目录
相关文章
|
1月前
|
Java C语言
用Java(C语言也可以看)实现冒泡排序和折半查找(详细过程图)+逆序数组
用Java(C语言也可以看)实现冒泡排序和折半查找(详细过程图)+逆序数组
28 0
|
6月前
|
存储 算法 C语言
C语言---数据结构实验---哈夫曼树及哈夫曼编码的算法实现---图的基本操作
C语言---数据结构实验---哈夫曼树及哈夫曼编码的算法实现---图的基本操作
|
9月前
|
存储 机器学习/深度学习 C语言
c语言数据结构-图的操作
c语言数据结构-图的操作
|
9月前
|
C语言
c语言数据结构-图的概念
c语言数据结构-图的概念
|
9月前
|
存储 人工智能 算法
数据结构入门(C语言版)图的概念和功能函数实现
图是一种比线性表和树更复杂的数据结构。在线性表中,数据元素之间仅有线性关系每个元素只有一个直接前驱和一个直接后继。在树形结构中,数据元素之间存在明显的层次关系,并且每层的元素可能和下一层的多个元素(即其孩子结点)相邻,但只能和上一层的个元素(即其双亲结点)相邻。
|
9月前
|
算法 C语言
C语言--离散数学实验--图的基本概念及其应用
C语言--离散数学实验--图的基本概念及其应用
|
9月前
|
C语言
C语言---野指针的产生及避免(内存图解释说明)
C语言---野指针的产生及避免(内存图解释说明)
55 1
|
10月前
|
C语言
C语言有关char数组的一个经典例题及char的取值范围推导的思维图
C语言有关char数组的一个经典例题及char的取值范围推导的思维图
|
11月前
|
C语言
C语言《数据结构》——图的概念和创建,遍历
C语言《数据结构》——图的概念和创建,遍历
379 0
|
C语言
C语言典型例题七——菱形图
菱形图 C语言输出菱形图的原理:循环控制空格数和“*”的数量 空格数由菱形的对角线长减1除2开始,逐行减1,减至0后再逐行加1 *的数量由1开始,逐行加2,当空格数为0后,逐行减2,减至1,结束循环。