0

我正在制作一个用 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) ) 时,图形是方形的,但两者都是一样的,而是这样更准确为什么会这样。

这些东西在书中没有解释,所以我问你。

4

1 回答 1

1

我将从 2 开始,这基本上是整数除法的行为的副本?.

简而言之:除法运算符接受两个操作数并返回一个足够大且精确到足以容纳任何操作数的类型的值。因此,整数除法将始终产生整数结果,因为任何整数都足够精确以容纳整数。如您所知,整数除法可能会产生实数,因此至少有一个操作数必须是实数。例如#define TWOPI (2*(22.0/7)) // implicit conversion#define TWOPI (2*((float)22/7) // explicit conversion。这解释了方形图

  1. C 提供了两种类型的容器变量:数组和结构。数组是具有相同类型的值的集合,而结构是具有任意类型的值的集合。使用运算符访问数组成员[]并提供元素的索引(array[0]对于偏移 0 的元素,产生第一个元素)。使用.运算符(或->)访问结构,提供元素的名称
    所以apt[i]基本上意味着“从apt被 i 偏移的数组中获取一个元素”,或者换句话说“i+1从名为的数组中获取第一个元素apt”。添加一个.x意味着“好的,因为apt包含其他容器的元素采用名为x",方便地表示正弦波中点的 x 坐标。
    与 .y 相同,只是在那里我们有一个正弦函数的数学表示,具有可变比例。

编辑[解释数学]:
1 1-sin()。正弦函数的值在范围内R = [-1;1],因此1-R = [2;0]。这导致函数被反转(对正弦没有“视觉”影响)并向上移动到正值。在实践中,这允许在不处理负值的情况下添加高度乘数。即该函数仅从零点“增长”,并且不会从中心点在两个方向上“扩展”。
2.里面有什么sin()。您正在将 i 从 0 迭代到NUM. 在sin()你里面有一些乘以i/NUM。如果您在纸上进行分析,您会发现每次迭代TWOPI都会乘以 1/10、2/10、3/10 等。sin()期望其以弧度为单位的参数,并且在区域 [0; 2π]。所以乘以 2 PI 基本上意味着您代表的是正弦波的一个周期。将其更改为 4 PI 将导致 2 个正弦波周期。

于 2013-06-27T12:34:38.430 回答