早就想发本辑内容了,一直忙忙人生路……昨天一早听说飞机失联了,默默帮机上乘客及乘客们的亲属们祈祷。
之后发现以前同事在飞机上,顿时感觉整个人都不好了,第一次这样的事情离自己这样近,心里比自己乘飞机遇到颠簸时还忐忑。
先为同事求个祝福,他家孩子好小的说。
===============分割线===============梳理情绪===============
不知道为什么,本辑内容居然和这件事还有那么一点点的联系。楼主很早就想做个雷达扫描效果的玩意,来测量周围的物体,想到最简单的就是用超声波测量周围360°是否有半径范围内的物体,如果有就在屏幕上画个小点,然后根据扫描角度,绘制一个扫描的动画。两个内容,一个是旋转的扫描区,一个是坐标图上的小点点,两个内容一定要重合显示在一起,这样就用到了显示中的分层。
本辑的重点内容就是,如何利用屏幕的Layer来实现雷达扫描效果。
其实说了这一堆,分层问题是最简单的,我们最后来设置。首先要能够描画我们的画面元素。第一个是扫描区。
扫描区是一个扇形,并且还有明暗渐变,为了方便使用,我把扫描区做成一个数组单独存放,并在程序开始初始化这个数组,方法就是一个一个点的计算它的颜色值,雷达一般都是绿色的扫描效果……
- void CreateScanner(void)
- {
- u8 i,j;
- u32 tan;
- memset(scanner, 0, 100*100*2);
- for(j = 0; j < 100; j++)
- {
- for(i = 0; i < 100; i++)
- {
- if((i*i + j*j) <= 10000)
- {
- if(i>j)
- {
- break;
- }
- else
- {
- tan = 0xFF * i / j;
- scanner[j*100+i] = (tan << 3) & 0x7E0;
- }
- }
- else
- {
- break;
- }
- }
- }
- }
一开始我描绘扫描区的时候,是把scanner绕原点旋转画在最终坐标图上,可是那样的话,函数对应关系就不正确了,可能scanner的多个点映射到坐标图上的同一个点,这样绘制的结果就是坐标图上有些点应该是绿色,可是却没有上色。正确的方法应该是把坐标图上的点映射到scanner上,来判读每一个坐标点应该显示的颜色。好吧,先不考虑效率啦
- void DrawScanner(u16 r)
- {
- s32 i,j;
- s32 x,y;
-
- memset(frameScanner,0,0x50000);
-
- r = (r + 360 - 45) % 360;
-
- for(x = -99; x < 100; x++)
- {
- for(y = -99; y < 100; y++)
- {
- i = fcos[r] * x - fsin[r] * y;
- j = fsin[r] * x + fcos[r] * y;
- if(i>0&&i<100&&j>0&&j<100)
- ((u16*)frameScanner)[(x+160) * 240 + y + 120] = scanner[j * 100 + i];
- }
- }
- }
以上内容描画在上面的层中,作为扫描区备用。
接下来描画坐标区,
坐标区应该有个坐标图,我暂且做了个带有十字的两个同心圆,在这上面画发现的目标。根据雷达扫描效果,发现的目标会渐渐消失,可以使颜色渐渐消去,不过我选了另类的办法,让表示目标的圆点变小消失。
要绘制的目标我放在了一个数组中。s16 obj[0x200][3],每个对象都具有x,y和“显示浓度”。
- void DrawObjects(void)
- {
- u32 i;
-
- memset(&frameScanner[0x50000],0,0x50000);
-
- LCD_SetColors(0xFFFF,0x0000);
-
- i = obj_index;
- while(obj[i][OBJ_TIP]>0)
- {
- s32 r = obj[i][OBJ_TIP]/45;
- if(r > 0)
- {
- LCD_DrawFullCircle(obj[i][OBJ_X],obj[i][OBJ_Y],r);
- }
-
- i = 0x1FF & (i+1);
- }
-
- LCD_SetColors(0x07E0,0x0000);
-
- LCD_DrawCircle(120,160,45);
- LCD_DrawCircle(120,160,100);
- LCD_DrawLine(120,60,200,LCD_DIR_VERTICAL);
- LCD_DrawLine(20,160,200,LCD_DIR_HORIZONTAL);
-
- }
因为懒,所以上面描画了目标对象以后,直接画坐标同心圆了。
至于对象从哪里来,每次转一个角度都调用个dst = GetObjDistance(r);算好位置保存起来。我没有小雷达,暂且造些假数据了。
这些对象,绘制在下面的层中。要想显示正确,我们需要把上面的一个层设置上透明度。
- /* Alpha constant (255 totally opaque) */
- LTDC_Layer_InitStruct.LTDC_ConstantAlpha = 128;
最后,360°的sin值和cos值不要现算,而是事先算好存在数组里了。
可以看效果了。
最后的最后,分享工程,献丑了,实在是没有什么心情继续完善了。
Radar.rar
(420.92 KB)
(下载次数: 22, 2014-3-9 11:13 上传)
怎么到现在也没有个准消息……