c/old/old_gfx_plot.c · 4490 字节 · 下载原文
/* old_gfx_plot.c —— 函数曲线(图形界面)
* old_gfx_plot.c -- function curves (graphical window)
*
* 类别:graphic
* Category: graphic
* 兼容面:用 `ui_2d_line` 逐段连成曲线 + `ui_2d_pixel` 画散点 + 整数三角函数表。
* Compatibility: joining segment by segment with `ui_2d_line` to form a curve + `ui_2d_pixel` for scatter points + an integer trig table.
* 对应 BGI 时代最常见的"画函数图像"练习。
* This is the counterpart of the most common "plot a function" exercise of the BGI era.
* 出处:自写。
* Origin: self-written.
*
* ⚠ 用**整数正弦表**而不是 `sin()`:一来当年 8 位机上算浮点三角函数很贵、
* ⚠ Use an **integer sine table** instead of `sin()`: for one thing, floating-point trig was expensive on 8-bit machines back then,
* 老程序普遍预存表;~~二来本平台的浮点数组/64 位几条路尚有问题(见台账)~~,
* so old programs commonly pre-stored the table; ~~for another, this platform's float-array / 64-bit paths still had problems (see the ledger)~~,
* ✅ **已修好(2026-10-04 复验)**:`float farr[8]; farr[1]=7.0f` 读回 **7.000**、`long la[4]` 四条全落地、
* ✅ **fixed (re-checked 2026-10-04)**: `float farr[8]; farr[1]=7.0f` reads back **7.000**, all four `long la[4]` land, and
* 全局 `double` 数组元素也正确 ⇒ 浮点数组/64 位那几条路现在都通。整数表**照旧保留**(能跑就别动)。
* global `double` array elements are correct too => those float-array / 64-bit paths all work now. The integer table **stays** (if it runs, do not touch it).
*/
#include <vml_ui.h>
#define W 320
#define H 240
#define PI2 256 /* 一个周期 256 个单位(老式定点写法)*/
/* One period is 256 units (the old fixed-point convention) */
/* 正弦表:值域 -100..100,一个周期 64 项 */
/* Sine table: range -100..100, 64 entries per period */
static int sintab[64] = {
0, 10, 20, 29, 38, 47, 56, 63,
71, 77, 83, 88, 92, 95, 98, 99,
100, 99, 98, 95, 92, 88, 83, 77,
71, 63, 56, 47, 38, 29, 20, 10,
0, -10, -20, -29, -38, -47, -56, -63,
-71, -77, -83, -88, -92, -95, -98, -99,
-100, -99, -98, -95, -92, -88, -83, -77,
-71, -63, -56, -47, -38, -29, -20, -10
};
static int isin(int t) { return sintab[t & 63]; }
int main(void)
{
int x, y0, y1, msg;
int lang; /* 界面语言:开局查一次 */
/* UI language: queried once at start */
lang = ui_scr_get_language();
ui_win_open(lang == 0 ? "老式绘图:函数曲线" : "Old-style gfx: function curves", W, H);
ui_2d_clear(0x101820);
/* 坐标轴 */
/* Axes */
ui_2d_line(0, H / 2, W, H / 2, 0x404A5A, 1); /* x 轴 */
/* x axis */
ui_2d_line(W / 2, 0, W / 2, H, 0x404A5A, 1); /* y 轴 */
/* y axis */
/* 正弦曲线:逐段连(老办法) */
/* Sine curve: joined segment by segment (the old way) */
y0 = H / 2;
for (x = 0; x < W; x++) {
y1 = H / 2 - isin(x) * (H / 2 - 20) / 100;
if (x > 0) ui_2d_line(x - 1, y0, x, y1, 0x61AFEF, 2);
y0 = y1;
}
/* 抛物线:y = (x-160)^2 / 40,整数算 */
/* Parabola: y = (x-160)^2 / 40, computed in integer arithmetic */
y0 = 0;
for (x = 0; x < W; x++) {
int d = x - W / 2;
y1 = d * d / 40;
if (y1 > H - 1) y1 = H - 1;
if (x > 0) ui_2d_line(x - 1, y0, x, y1, 0xE5C07B, 1);
y0 = y1;
}
/* 散点:用 ui_2d_pixel 打点(对照上面两种连法)*/
/* Scatter points: plotted with ui_2d_pixel (to compare with the two joining methods above) */
for (x = 0; x < W; x += 8)
ui_2d_pixel(x, H - 1 - (isin(x * 4) + 100) / 8, 0x98C379);
ui_2d_text(8, 8, lang == 0 ? "sin / 抛物线 / 散点" : "sin / parabola / scatter", 0xABB2BF, 16, VML_ANCHOR_LEFT);
ui_2d_present();
while (!ui_win_is_closed())
ui_msg_wait(&msg, 0); /* 画完等关窗,别立刻关(快照会没)*/
/* Wait for the window to close after drawing; do not close right away (the snapshot would be lost) */
ui_win_close();
return 0;
}