如何在YASM 8086中绘制[-π/2,π/2]区间的y=cos(x²+x+1)图像
解决方案:YASM 8086中限定区间绘制函数图像
核心问题分析
现有代码直接将屏幕X坐标(0-319)作为函数输入x值,导致绘制的是x∈[0,319]的函数图像,而非目标区间[-π/2, π/2]。需要建立屏幕坐标与数学坐标的映射关系,将屏幕X轴的0-319对应到[-π/2, π/2],同时保持Y轴的合理缩放。
坐标映射逻辑
1. 屏幕X → 数学x的转换
屏幕中心X=160对应数学x=0,屏幕左边界X=0对应x=-π/2,右边界X=319对应x≈π/2(误差可忽略)。转换公式:
数学x = (屏幕X - 160) * (π / 160)
解释:屏幕左右半区各160像素,对应数学区间±π/2,因此每像素对应的x增量是(π/2)/160 = π/160。
2. 数学y → 屏幕Y的转换
函数y=cos(...)的输出范围是[-1,1],需缩放后映射到屏幕Y轴:
- 屏幕中心Y=100对应y=0
- 用缩放因子(如60)将y的范围扩展为[-60,60],对应屏幕Y的40-160区间(在200分辨率内)
- 由于屏幕Y轴向下递增,需反转符号:
屏幕Y = 100 - (数学y * scaleY)
修改后的完整代码
;------------------------------------------------------------------------ %include 'yasmmac.inc' org 100h ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; section .text ; code starts here startas: call procSetGraphicsMode ; 绘制Y轴(垂直中线X=160) xor di, di ; Y从0开始 .vertical: mov si, 160 ; X固定为160 mov cl, 15 ; 白色 call procPutPixel inc di cmp di, 199 ; 到屏幕底部Y=199停止 jbe .vertical ; 绘制X轴(水平中线Y=100) xor si, si ; X从0开始 .horizontal: mov di, 100 ; Y固定为100 mov cl, 15 ; 白色 call procPutPixel inc si cmp si, 319 ; 到屏幕右边界X=319停止 jbe .horizontal ; 初始化浮点环境与常量 fninit fld dword [pi_over_160] ; st0 = π/160,用于X坐标缩放 .loop: ; 1. 将屏幕X转换为数学x:x = (si - 160) * (π/160) mov [screenX], si fild word [screenX] ; st0 = 屏幕X fiadd word [offsetX] ; st0 = 屏幕X - 160(offsetX为-160) fmul st0, st1 ; st0 = (X-160)*(π/160) → 目标区间的数学x ; 2. 计算x² + x + 1 fld st0 ; st1 = x, st0 = x fmul st0, st1 ; st0 = x² fadd st0, st1 ; st0 = x² + x fadd dword [one] ; st0 = x² + x + 1 ; 3. 计算cos值并转换为屏幕Y坐标 fcos ; st0 = cos(x²+x+1) ∈ [-1,1] fimul word [scaleY] ; st0 = cos值 * 60 ∈ [-60,60] fistp word [mathY] ; 存储计算结果 mov di, 100 ; 屏幕Y中心 sub di, [mathY] ; 反转Y轴方向,得到最终屏幕Y坐标 ; 绘制像素 mov cl, 4 ; 红色 call procPutPixel ; 循环遍历所有X坐标 inc si cmp si, 319 jbe .loop call procWaitForEsc exit %include 'yasmlib.asm' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; section .data ; data pi dd 3.1415926535 ; π常量 pi_over_160 dd 0.01963495408 ; π/160,用于X坐标缩放 one dd 1.0 ; 常量1 offsetX dw -160 ; 屏幕X到中心的偏移量 screenX dw 0 ; 存储当前屏幕X坐标 mathY dw 0 ; 存储计算后的数学y值 scaleY dw 60 ; Y轴缩放因子,控制图像高度 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; section .bss
关键修改说明
- 在
.data段添加了所需数学常量,简化坐标转换的浮点运算 - 重构循环内的逻辑:先完成屏幕X到目标区间数学x的转换,再代入函数计算
- 调整Y轴计算方向,适配屏幕Y轴向下递增的特性
- 移除冗余变量,优化浮点栈的使用效率
内容的提问来源于stack exchange,提问作者KazlLaur
相关产品推荐
相关产品推荐

