[原创] 晒设计方案+四点钟方向发现目标

sjtitr   2014-3-9 11:15 楼主
早就想发本辑内容了,一直忙忙人生路……昨天一早听说飞机失联了,默默帮机上乘客及乘客们的亲属们祈祷。

之后发现以前同事在飞机上,顿时感觉整个人都不好了,第一次这样的事情离自己这样近,心里比自己乘飞机遇到颠簸时还忐忑。

先为同事求个祝福,他家孩子好小的说。

===============分割线===============梳理情绪===============

不知道为什么,本辑内容居然和这件事还有那么一点点的联系。楼主很早就想做个雷达扫描效果的玩意,来测量周围的物体,想到最简单的就是用超声波测量周围360°是否有半径范围内的物体,如果有就在屏幕上画个小点,然后根据扫描角度,绘制一个扫描的动画。两个内容,一个是旋转的扫描区,一个是坐标图上的小点点,两个内容一定要重合显示在一起,这样就用到了显示中的分层。

IMG_0678.JPG


本辑的重点内容就是,如何利用屏幕的Layer来实现雷达扫描效果。

其实说了这一堆,分层问题是最简单的,我们最后来设置。首先要能够描画我们的画面元素。第一个是扫描区。

扫描区是一个扇形,并且还有明暗渐变,为了方便使用,我把扫描区做成一个数组单独存放,并在程序开始初始化这个数组,方法就是一个一个点的计算它的颜色值,雷达一般都是绿色的扫描效果……

  1. void CreateScanner(void)
  2. {
  3.   u8 i,j;
  4.   u32 tan;
  5.   memset(scanner, 0, 100*100*2);
  6.   for(j = 0; j < 100; j++)
  7.   {
  8.     for(i = 0; i < 100; i++)
  9.     {
  10.       if((i*i + j*j) <= 10000)
  11.       {
  12.         if(i>j)
  13.         {
  14.           break;
  15.         }
  16.         else
  17.         {
  18.           tan = 0xFF * i / j;
  19.           scanner[j*100+i] = (tan << 3) & 0x7E0;
  20.         }
  21.       }
  22.       else
  23.       {
  24.         break;
  25.       }
  26.     }
  27.   }
  28. }

一开始我描绘扫描区的时候,是把scanner绕原点旋转画在最终坐标图上,可是那样的话,函数对应关系就不正确了,可能scanner的多个点映射到坐标图上的同一个点,这样绘制的结果就是坐标图上有些点应该是绿色,可是却没有上色。正确的方法应该是把坐标图上的点映射到scanner上,来判读每一个坐标点应该显示的颜色。好吧,先不考虑效率啦

  1. void DrawScanner(u16 r)
  2. {
  3.   s32 i,j;
  4.   s32 x,y;
  5.   
  6.   memset(frameScanner,0,0x50000);
  7.   
  8.   r = (r + 360 - 45) % 360;
  9.   
  10.   for(x = -99; x < 100; x++)
  11.   {
  12.     for(y = -99; y < 100; y++)
  13.     {
  14.       i = fcos[r] * x - fsin[r] * y;
  15.       j = fsin[r] * x + fcos[r] * y;
  16.       if(i>0&&i<100&&j>0&&j<100)
  17.       ((u16*)frameScanner)[(x+160) * 240 + y + 120] = scanner[j * 100 + i];
  18.     }
  19.   }
  20. }

以上内容描画在上面的层中,作为扫描区备用。
接下来描画坐标区,

坐标区应该有个坐标图,我暂且做了个带有十字的两个同心圆,在这上面画发现的目标。根据雷达扫描效果,发现的目标会渐渐消失,可以使颜色渐渐消去,不过我选了另类的办法,让表示目标的圆点变小消失。

要绘制的目标我放在了一个数组中。s16 obj[0x200][3],每个对象都具有x,y和“显示浓度”。
  1. void DrawObjects(void)
  2. {
  3.   u32 i;
  4.   
  5.   memset(&frameScanner[0x50000],0,0x50000);
  6.   
  7.   LCD_SetColors(0xFFFF,0x0000);
  8.   
  9.   i = obj_index;
  10.   while(obj[i][OBJ_TIP]>0)
  11.   {
  12.     s32 r = obj[i][OBJ_TIP]/45;
  13.     if(r > 0)
  14.     {
  15.       LCD_DrawFullCircle(obj[i][OBJ_X],obj[i][OBJ_Y],r);
  16.     }
  17.    
  18.     i = 0x1FF & (i+1);
  19.   }
  20.   
  21.   LCD_SetColors(0x07E0,0x0000);

  22.   
  23.   LCD_DrawCircle(120,160,45);
  24.   LCD_DrawCircle(120,160,100);
  25.   LCD_DrawLine(120,60,200,LCD_DIR_VERTICAL);
  26.   LCD_DrawLine(20,160,200,LCD_DIR_HORIZONTAL);
  27.   
  28. }

因为懒,所以上面描画了目标对象以后,直接画坐标同心圆了。

至于对象从哪里来,每次转一个角度都调用个dst = GetObjDistance(r);算好位置保存起来。我没有小雷达,暂且造些假数据了。

这些对象,绘制在下面的层中。要想显示正确,我们需要把上面的一个层设置上透明度。
  1.   /* Alpha constant (255 totally opaque) */
  2.   LTDC_Layer_InitStruct.LTDC_ConstantAlpha = 128;

最后,360°的sin值和cos值不要现算,而是事先算好存在数组里了。


可以看效果了。
IMG_0678.gif



最后的最后,分享工程,献丑了,实在是没有什么心情继续完善了。
Radar.rar (420.92 KB)
(下载次数: 22, 2014-3-9 11:13 上传)




怎么到现在也没有个准消息……

回复评论 (10)

2推荐 季夏木槿 

memset(frameScanner,0,0x50000);这个是什么意思啊
点赞  2014-7-8 21:42
高手在民间
点赞  2014-3-10 10:22
霸气十足
淘宝:https://viiot.taobao.com/Q群243090717 多年专业物联网行业经验,个人承接各类物联网外包项目
点赞  2014-3-11 11:07
希望看到楼主更多的分享。
一别四五年,变化万千。https://home.eeworld.com.cn/static/image/smiley/comcom/5.gif[/img]
点赞  2014-3-11 11:07
扫描显示效果不错,值得学习
http://weibo.com/u/1391449055
点赞  2014-3-11 14:08
关于民航失联事件你我的状态居然是一样的,我也是知道以前的同事在机上后整个感觉很震惊。如此小概率事件怎么跟自己好像很近。一起来为他们祈祷,希望奇迹发生。
点赞  2014-3-11 21:58
没有看懂是怎么回事,能不能交流一下
哈喽,我是卡索KaSuo~~
点赞  2014-7-6 14:47
引用: 季夏木槿 发表于 2014-7-6 14:47
没有看懂是怎么回事,能不能交流一下

可以啊
点赞  2014-7-7 09:19
谢谢
点赞  2014-7-8 19:56
引用: 季夏木槿 发表于 2014-7-8 21:42
memset(frameScanner,0,0x50000);这个是什么意思啊

是标准库函数,从指定地址开始填充数据0,一共填充0x50000个字节
点赞  2014-7-9 05:45
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复