不用浮点运算的3D图形算法~
用浮点运算很浪费时间, 于是就想了一个办法...
屏幕坐标都是整数, 我们不需要尾数, 把一个0.0000000 ~ 1.0000000 的数表示成0x00~0x80,最高位和低7位的中间是小数点, 由于二进制小数表示十进制小数会有误差,只能取近似值, 比如0.7880108,取0.7890625也就是0x65, 要把一个二进制整数调整成0.7890625倍, 只需要用0x65乘上那个整数再右移7位, OK , 按这个思路弄进程序里面运行...

运行效果:
http://www.tudou.com/programs/view/TNCI_Cbmb-E/
点击此处查看视频


测试.png

测试1.png

KC-LS1u机原理图 : https://www.kechuang.org/t/71330
KC-LS1u的C程序代码(乱七八糟的写来测试一下,暂时没进行特别优化, 即兴编写):
#include<io.h>

int sin[91] =  //格式 : 低8位的最高位为整数,尾数为小数
{
0x00, //sin(0) = 0 无误差
0x02, //sin(1) = 0.0174524,这里取值0.015625
0x04, //sin(2) = 0.0348995,这里取值0.03125
0x07, //sin(3) = 0.052336,这里取值0.0546875
0x09, //sin(4) = 0.0697565,这里取值0.0703125
0x0b, //sin(5) = 0.0871557,这里取值0.0859375
0x0d, //sin(6) = 0.1045285,这里取值0.1015625
0x10, //sin(7) = 0.1218693,这里取值0.125
0x12, //sin(8) = 0.1391731,这里取值0.140625
0x14, //sin(9) = 0.1564344,这里取值0.15625
0x16, //sin(10) = 0.1736482,这里取值0.171875
0x18, //sin(11) = 0.190809,这里取值0.1875
0x1b, //sin(12) = 0.2079117,这里取值0.2109375
0x1d, //sin(13) = 0.2249511,这里取值0.2265625
0x1f, //sin(14) = 0.2419219,这里取值0.2421875
0x21, //sin(15) = 0.258819,这里取值0.2578125
0x23, //sin(16) = 0.2756374,这里取值0.2734375
0x25, //sin(17) = 0.2923717,这里取值0.2890625
0x28, //sin(18) = 0.309017,这里取值0.3125
0x2a, //sin(19) = 0.3255682,这里取值0.328125
0x2c, //sin(20) = 0.3420201,这里取值0.34375
0x2e, //sin(21) = 0.3583679,这里取值0.359375
0x30, //sin(22) = 0.3746066,这里取值0.375
0x32, //sin(23) = 0.3907311,这里取值0.390625
0x34, //sin(24) = 0.4067366,这里取值0.40625
0x36, //sin(25) = 0.4226183,这里取值0.421875
0x38, //sin(26) = 0.4383711,这里取值0.4375
0x3a, //sin(27) = 0.4539905,这里取值0.453125
0x3c, //sin(28) = 0.4694716,这里取值0.46875
0x3e, //sin(29) = 0.4848096,这里取值0.484375
0x40, //sin(30) = 0.5, 无误差
0x42, //sin(31) = 0.5150381,这里取值0.515625
0x44, //sin(32) = 0.5299193,这里取值0.53125
0x46, //sin(33) = 0.544639,这里取值0.546875
0x48, //sin(34) = 0.5591929,这里取值0.5625
0x49, //sin(35) = 0.5735764,这里取值0.5703125
0x4b, //sin(36) = 0.5877852,这里取值0.5859375
0x4d, //sin(37) = 0.601815,这里取值0.6015625
0x4f, //sin(38) = 0.6156615,这里取值0.6171875
0x51, //sin(39) = 0.6293204,这里取值0.6328125
0x52, //sin(40) = 0.6427876,这里取值0.640625
0x54, //sin(41) = 0.656059,这里取值0.65625
0x56, //sin(42) = 0.6691306,这里取值0.671875
0x57, //sin(43) = 0.6819984,这里取值0.6796875
0x59, //sin(44) = 0.6946584,这里取值0.6953125
0x5a, //sin(45) = 0.7071068,这里取值0.7109375
0x5c, //sin(46) = 0.7193398,这里取值0.71875
0x5e, //sin(47) = 0.7313537,这里取值0.734375
0x5f, //sin(48) = 0.7431448,这里取值0.7421875
0x61, //sin(49) = 0.7547096,这里取值0.7578125
0x62, //sin(50) = 0.7660444,这里取值0.765625
0x63, //sin(51) = 0.777146,这里取值0.7734375
0x65, //sin(52) = 0.7880108,这里取值0.7890625
0x66, //sin(53) = 0.7986355,这里取值0.796875
0x68, //sin(54) = 0.809017,这里取值0.8125
0x69, //sin(55) = 0.819152,这里取值0.8203125
0x6a, //sin(56) = 0.8290376,这里取值0.828125
0x6b, //sin(57) = 0.838671,这里取值0.8359375
0x6d, //sin(58) = 0.8480481,这里取值0.8515625
0x6e, //sin(59) = 0.8571673,这里取值0.859375
0x6f, //sin(60) = 0.8660254,这里取值0.8671875
0x70, //sin(61) = 0.8746197,这里取值0.875
0x71, //sin(62) = 0.8829476,这里取值0.8828125
0x72, //sin(63) = 0.8910065,这里取值0.890625
0x73, //sin(64) = 0.8987941,这里取值0.8984375
0x74, //sin(65) = 0.9063078,这里取值0.90625
0x75, //sin(66) = 0.9135455,这里取值0.9140625
0x76, //sin(67) = 0.9205049,这里取值0.921875
0x77, //sin(68) = 0.9271839,这里取值0.9296875
0x78, //sin(69) = 0.9335804,这里取值0.9375
0x78, //sin(70) = 0.9396926,这里取值0.9375
0x79, //sin(71) = 0.9455186,这里取值0.9453125
0x7a, //sin(72) = 0.9510565,这里取值0.953125
0x7a, //sin(73) = 0.9563048,这里取值0.953125
0x7b, //sin(74) = 0.9612617,这里取值0.9609375
0x7c, //sin(75) = 0.9659258,这里取值0.96875
0x7c, //sin(76) = 0.9702957,这里取值0.96875
0x7d, //sin(77) = 0.9743701,这里取值0.9765625
0x7d, //sin(78) = 0.9781476,这里取值0.9765625
0x7e, //sin(79) = 0.9816272,这里取值0.984375
0x7e, //sin(80) = 0.9848078,这里取值0.984375
0x7e, //sin(81) = 0.9876883,这里取值0.984375
0x7f, //sin(82) = 0.9902681,这里取值0.9921875
0x7f, //sin(83) = 0.9925462,这里取值0.9921875
0x7f, //sin(84) = 0.9945219,这里取值0.9921875
0x7f, //sin(85) = 0.9961947,这里取值0.9921875
0x80, //sin(86) = 0.9975641,这里取值1
0x80, //sin(87) = 0.9984295,这里取值1
0x80, //sin(88) = 0.9993908,这里取值1
0x80, //sin(89) = 0.9998477,这里取值1
0x80  //sin(90) = 1,这里取值1
};


int sin_360[361];
int cos_360[361];


void sin_cos_csh()
{
unsigned int D = 0;
while(D != 361)
{
   if(D < 91) //角度为0到90度 取出sin值和cos值
   {
      sin_360[D] = sin[D];
      cos_360[D] = sin[90 - D];
   }
   else if(D > 90 && D < 181) //角度为91到180度 取出sin值和cos值
   {
      sin_360[D] = sin[180 - D];
      cos_360[D] = -sin[D - 90];
   }
   else if(D > 180 && D < 271) //角度为181到270度 取出sin值和cos值
   {
      sin_360[D] = -sin[D - 180];
      cos_360[D] = -sin[270 - D];
   }
   else //角度为271到360度 取出sin值和cos值
   {
      sin_360[D] = -sin[360 - D];
      cos_360[D] = sin[D - 270];
   }
   ++D;
}
}

void yuan(VRAMY,VRAMX,XD,YD,ZD,r,VRAM_DATA)
{
   int dd = 0,Y,X,Z,y,x,_sin,_cos;
   int _Y,_X,_Z;
   do
   {
      _sin = sin_360[dd];
      _cos = cos_360[dd];
      X = _cos*r >> 7;
      _Y = _sin*r >> 7;
      _sin = sin_360[XD];
      _cos = cos_360[XD];
      Y = _cos*_Y >> 7;
      _Z = _sin*_Y >> 7;
      _sin = sin_360[YD];
      _cos = cos_360[YD];
//     Z = _cos*_Z - _sin*X >> 7;
      _X = _sin*_Z + _cos*X >> 7;
      _sin = sin_360[ZD];
      _cos = cos_360[ZD];
      X = _cos*_X - _sin*Y >> 7;
      Y = _sin*_X + _cos*Y >> 7;

      y = VRAMY - Y; //转换为实际坐标
      x = VRAMX + X;
      VRAM[(y << 8) | (x & 0x00ff)] = VRAM_DATA; //写入显存
      dd += 10;
   }while(dd < 360);
}

void VRAM_qingping(unsigned char Y,unsigned char _Y,unsigned char DATA)
{
while(Y != _Y)
{
   _B = DATA;
   _A = 0;
   do
   {
     _A1 = Y;
     _A2 = 0x80;
     _A0 = _A;
     _NOP;
     _RAM = _B;
     _A = _A + 1;
     _A0 = _A;
     _NOP;
     _RAM = _B;
     _A = _A + 1;
     _A0 = _A;
     _NOP;
     _RAM = _B;
     _A = _A + 1;
     _A0 = _A;
     _NOP;
     _RAM = _B;
     _A = _A + 1;
     _A0 = _A;
     _NOP;
     _RAM = _B;
     _A = _A + 1;
     _A0 = _A;
     _NOP;
     _RAM = _B;
     _A = _A + 1;
     _A0 = _A;
     _NOP;
     _RAM = _B;
     _A = _A + 1;
     _A0 = _A;
     _NOP;
     _RAM = _B;
     _A = _A + 1;
   }while(_SUB_A_1 != -1);
   ++Y;
}

}

void zhongxinzhou(VRAMY,VRAMX,XD,YD,ZD,VRAM_DATA)
{

   int zz = -32,Y,X,Z,y,x,_sin,_cos;
   int _Y,_X,_Z;
   do
   {
      _sin = sin_360[XD];
      _cos = cos_360[XD];
      Y = - _sin*zz >> 7;
      _Z =  _cos*zz >> 7;
      _sin = sin_360[YD];
      _cos = cos_360[YD];
//     Z = _cos*_Z >> 7;
      _X = _sin*_Z >> 7;
      _sin = sin_360[ZD];
      _cos = cos_360[ZD];
      X = _cos*_X - _sin*Y >> 7;
      Y = _sin*_X + _cos*Y >> 7;

      y = VRAMY - Y; //转换为实际坐标
      x = VRAMX + X;
      VRAM[(y << 8) | (x & 0x00ff)] = VRAM_DATA; //写入显存
      zz += 4;
   }while(zz < 32);


}

main()
{
   int i,YD = 0,XD = 0,ZD = 0;
   VRAM_qingping(0,240,0x00);
   sin_cos_csh();
   while(1)
   {
      CTVGA_C &= ~0x01; //请求访问VRAM
      while((CTVGA_C & 0x80) == 0x80); //可以访问的时候跳出
      VRAM_qingping(120 - 100,120 + 100,0x00);

    //  ++YD;
   //   ++YD;
   //   if(YD == 360) YD = 0;
      ++XD;
      ++XD;
      ++XD;
      if(XD == 360) XD = 0;
      ++ZD;
      if(ZD == 360) ZD = 0;

      zhongxinzhou(120,128,XD,YD,ZD,0x1f);
      yuan(120,128,XD,YD,ZD,32,0x03);
      yuan(120,128,XD,YD,ZD,64,0xe0);
      yuan(120,128,XD,YD,ZD,80,0x13);
      yuan(120,128,XD,YD,ZD,96,0xe5);

      CTVGA_C |= 0x01; //请求VRAM显示
      for(i = 0;i != 7000;++i);
   }

}
来自:计算机科学 / 机器学习
 
2015-5-4 4:10:09
神之觉醒(作者)
1楼
只需要大量整数乘法运算和移位运算.. 很容易构建一个简单的硬件运算器, 加速运算~~~~
折叠评论
加载评论中,请稍候...
折叠评论
2015-5-4 9:19:23
2楼
你这是TI使用的Q格式。。你可以看看他们的库。。写的很全。。算法很多
折叠评论
加载评论中,请稍候...
折叠评论
3楼
编译器用的是什么
折叠评论
加载评论中,请稍候...
折叠评论
4楼
现在FPU那么普及了,定点数优势不大啊。
折叠评论
加载评论中,请稍候...
折叠评论
5楼
不懂c,菜鸟一枚得去把c弄懂先[s::lol]
折叠评论
加载评论中,请稍候...
折叠评论
6楼
不错,感觉略屌,可是帧率好像有点低,一卡一卡的
折叠评论
加载评论中,请稍候...
折叠评论
7楼
不错,查表法[s::lol]
不过目测有误差抖动,帧率也有点小。。。有FPU的话还是用浮点数好了
折叠评论
加载评论中,请稍候...
折叠评论
8楼
楼主应该赶快开发第二代CPU
折叠评论
加载评论中,请稍候...
折叠评论
神之觉醒(作者)
9楼
引用 smith:
编译器用的是什么
独家搭配KC-LS1uC编译器, 每行代码都亲自动手..
折叠评论
加载评论中,请稍候...
折叠评论
神之觉醒(作者)
10楼
引用 .........:
现在FPU那么普及了,定点数优势不大啊。
看场合
折叠评论
加载评论中,请稍候...
折叠评论
神之觉醒(作者)
11楼
引用 cccyl:
不错,感觉略屌,可是帧率好像有点低,一卡一卡的
暂时只能做到这样了... https://www.kechuang.org/t/71398
折叠评论
加载评论中,请稍候...
折叠评论
神之觉醒(作者)
12楼
引用 acmilan:
不错,查表法
不过目测有误差抖动,帧率也有点小。。。有FPU的话还是用浮点数好了
嗯~ 查表法很常见的   这里核心是一个整数和一个小数相乘
折叠评论
加载评论中,请稍候...
折叠评论
神之觉醒(作者)
13楼
引用 fshwen:
楼主应该赶快开发第二代CPU
第二代玩具CPU, 可能会N个CPU并行处理~
折叠评论
加载评论中,请稍候...
折叠评论
2015-05-05 18:03:46
14楼
想法不错
折叠评论
加载评论中,请稍候...
折叠评论
2015-05-06 23:13:33
2015-5-6 23:13:33
神之觉醒(作者)
15楼
这个经典的坐标变换挺好玩的, 通过组合变换可以让空间坐标绕Z轴X轴Y轴旋转~~~  转转转转转转转转转转转转转转转转转转转转转转转转转转转转转转转转

绕Z轴旋转:
X = cos(角度)*X - sin(角度)*Y;
Y =  sin(角度)*X + cos(角度)*Y;

绕X轴旋转:
Y = cos(角度)*Y - sin(角度)*Z;
Z =  sin(角度)*Y + cos(角度)*Z;

绕Y轴旋转:
Z = cos(角度)*Z - sin(角度)*X;
X =  sin(角度)*Z + cos(角度)*X;


然后再加上缩放平移神魔的......  就可以用代码构建一个属于你的3D世界....  高级点的话再弄填充、纹理、光照上去~~
折叠评论
加载评论中,请稍候...
折叠评论
2015-05-09 20:49:25
2015-5-9 20:49:25
16楼
浮点模块貌似就是前x位做数字位,后y位做小数点,大约相当于X*10^y的样子吧。。。然后算起来前面的归前面的,后面的归后面的。。。。事实上就是搞得复杂点的整数ALU。。。。记得不太清楚了。。。
折叠评论
加载评论中,请稍候...
折叠评论
2015-05-23 15:59:10
2015-5-23 15:59:10
17楼
楼主的8位计算机?搞3D运算的话还是要有强大的FPU,不然很吃力。
折叠评论
加载评论中,请稍候...
折叠评论
2015-07-22 18:02:12
2015-7-22 18:02:12
18楼
void yuan(VRAMY,VRAMX,XD,YD,ZD,r,VRAM_DATA)
求头文件<io.h>...[s::)]
我也想写一个编译器
最近看了Linux0.11把内核写进你的机
折叠评论
加载评论中,请稍候...
折叠评论
神之觉醒(作者)
19楼
引用 strange:
void yuan(VRAMY,VRAMX,XD,YD,ZD,r,VRAM_DATA)
求头文件<io.h>...
我也想写一个编译器
最近看了Linux0.11把内核写进你的机
要是在其他机上跑, 直接操作显存 "VRAM" , "VRAM" 这里是一个数组, 偏移低8位是X坐标, 高8位是Y坐标, 写入数组的数据是8位像素数据,  其他机上跑有 "CTVGA_C" 的语句可以不用, 还有main函数下面那个for 7000延时也不用,

VRAM_qingping() 是擦除屏幕, 里面有机器码.. 要是想跑的话, 改下这个函数OK, <io.h> 暂时没什么东西..

Linux  没详细研究= = 不知道能不能跑,
折叠评论
加载评论中,请稍候...
折叠评论
2015-09-21 22:03:18
2015-9-21 22:03:18
20楼
引用 神之觉醒:
要是在其他机上跑, 直接操作显存 "VRAM" , "VRAM" 这里是一个数组, 偏移低8位是X坐标, 高8位是Y坐标, 写入数组的数据是8位像素数据,  其他机上跑有 "CTVGA_C" 的语句可以不用, 还有main函数下面那个for...
我还没搞懂怎么让屏幕显示图案,跟别说3D变化了
折叠评论
加载评论中,请稍候...
折叠评论
2015-09-22 22:17:56
2015-9-22 22:17:56
21楼
有想法应该支持,先顶一个
折叠评论
加载评论中,请稍候...
折叠评论
2015-09-25 20:59:14
2015-9-25 20:59:14
22楼
其实我看不懂你写的。你这是用C语言的吗?
折叠评论
加载评论中,请稍候...
折叠评论
2016-10-23 12:06:37
2016-10-23 12:06:37
23楼
感觉挺不错的,如果用透视投影就好了→_→

[修改于 4 年前 - 2016-10-23 12:38:23]

折叠评论
加载评论中,请稍候...
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

神之觉醒
学者 机友 笔友
文章
67
回复
1117
学术分
4
2011/08/12注册,4 个月前活动
暂无简介
插入资源
全部
图片
视频
音频
附件
全部
未使用
已使用
正在上传
空空如也~
上传中..{{f.progress}}%
处理中..
上传失败,点击重试
{{f.name}}
空空如也~
(视频){{r.oname}}
{{selectedResourcesId.indexOf(r.rid) + 1}}
插入表情
我的表情
共享表情
Emoji
上传
注意事项
最大尺寸100px,超过会被压缩。为保证效果,建议上传前自行处理。
建议上传自己DIY的表情,严禁上传侵权内容。
点击重试等待上传{{s.progress}}%处理中...已上传
空空如也~
草稿箱
加载中...
此处只插入正文,如果要使用草稿中的其余内容,请点击继续创作。
{{fromNow(d.toc)}}
{{getDraftInfo(d)}}
标题:{{d.t}}
内容:{{d.c}}
继续创作
删除插入插入
{{forum.displayName}}
{{forum.countThreads}}
篇文章,
{{forum.countPosts}}
条回复
{{forum.description || "暂无简介"}}
ID: {{user.uid}}
学术分隐藏
{{submitted?"":"投诉"}}
请选择违规类型:
{{reason.description}}
支持的图片格式:jpg, jpeg, png