我当时正在编写一个用于在C语言中显示正弦图的程序,
这是程序的一小部分
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int cxClient, cyClient;
HDC hdc;
int i;
PAINTSTRUCT ps;
POINT apt[NUM];
switch (message)
{
case WM_SIZE:
cXClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
MoveToEx(hdc, 0, cyClient / 2, 0);
LineTo(hdc, cxClient, cyClient / 2);
for (i = 0; i < NUM; i++)
{
apt[i].x = i * cxClient / NUM;
apt[i].y = (int) (height / 2 * (1 - sin(TWOPI * i / NUM)));
}
Polyline(hdc, apt, NUM);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
其中NUM设置为1000,cxClient是低位字的客户区的宽度,cyClient是高位字的客户区的高度,TWOPI全局定义为(2 * 3.1459)
我的程序问题是
1.我无法理解apt [i] .x和apt [i] .y行(包括正弦形式)。
2.当我将TWOPI定义为#define TWOPI(2 *(22/7))而不是(#define TWOPI(2 * 3.1459))时,该图是正方形的,但是两者都是相同的,所以这样更准确为什么会这样。
这些东西在书中没有解释,所以我问你。
最佳答案
我将从2开始,它基本上是What is the behavior of integer division?的副本。
简而言之:除法运算符同时使用两个操作数,并以足够大且精确的类型返回值,以容纳任何操作数。因此,整数除法将始终产生整数结果,因为任何整数都足够精确以容纳整数。如您所知,整数除法可能会得出实数值,因此至少一个操作数必须是实数。例如#define TWOPI (2*(22.0/7)) // implicit conversion
或#define TWOPI (2*((float)22/7) // explicit conversion
。这解释了方形图
C提供了两种类型的容器变量:数组和结构。数组是具有相同类型的值的集合,而结构是具有任意类型的值的集合。使用[]
运算符访问数组的成员并提供元素的索引(对于偏移0的元素,array[0]
产生第一个元素)。使用.
运算符(或->
)访问结构,并提供元素的名称。
因此,apt[i]
基本上意味着“从数组i中偏移了i的元素中获取元素”,换句话说,就是“从名为apt
的数组中获取了i+1
个元素”。添加apt
表示“好吧,因为.x
的元素包含其他容器,请使用名为apt
的元素”,这方便地表示正弦波中该点的x坐标。
与.y相同,只是在这里我们有了一个可变比例的正弦函数的数学表示。
编辑[解释数学]:
1. x
。正弦函数的值在1-sin()
范围内,因此在R = [-1;1]
范围内。这导致功能反转(正弦上没有“视觉”效果)并向上移动到正值。实际上,这允许在不处理负值的情况下增加高度倍增器。即该函数仅从零点开始“增长”,而没有从中心点沿两个方向“扩展”。
2. 1-R = [2;0]
里面有什么。您正在将i从0迭代到sin()
。在NUM
内部,您可以乘以sin()
。如果您在纸上进行分析,则每次迭代都会得到i/NUM
乘以1 / 10、2 / 10、3 / 10等。TWOPI
期望其参数以弧度和“全”正弦波(一个周期)可在区域[0; 2π]。因此,乘以2 PI基本上意味着您代表一个正弦波的一个周期。将其更改为4 PI将导致2个周期的正弦波。
关于c - 制作SINE WAVE程序,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17337475/