上一篇文章介绍了实时跟踪程序中画点的操作,在这里介绍如果实现程序跟踪的动画回放。实现动画回放的基本原理是不停的刷新JPanel,在每次刷新的过程中,把图片画在相邻的位置便可以实现动画的效果。
       为了实现动画的回放,需要使用Thread进行不停的刷新。回顾一下线路数据结构:线路的ID,线路的名称,线路的所有点的集合,线路的图片名称,线路的交通工具,为了实现动画,还需要为线路添加一个记录动画位置的类,命名为Cartoon,Cartoon类包含了当前动画位置的curX,curY 坐标,当前倾斜的角度angle,在画JPanel的painComponent方法中调用路线的画图方法,便可以画出线路,Route类需要遍历每个Stone点,对于每个点调用点的画图方法,之后再根据点的先后画出两个点之间的连线,在连线也画好的情况下再根据Cartoon的坐标和旋转角度画出相应的交通工具,这就是线路画图的所有步骤。另外在必要的情况下开启一个线程,线程拥有指向JPanel的句柄,从JPanel中获取线路的句柄,再从线路的句柄中获取Cartoon的句柄,线程便可以根据线路中的两个点计算刷新时图片的位置,线程休眠一段时间,再次计算图片的位置,调用JPanel进行刷新,反复执行,便可以得到动画。在这个过程中,线程的开始可以由事件触发,线程的结束可以根据当前线路是否已经到达最后来作为退出条件,或者被中断。
       假设目前动画需要走的线段由两个点决定,比如preStone,前一个点,curStone当前点。图标需要从preStone走到curStone,首先需要计算出目前行进的角度,确定角度的目的是使得图标做出相应的旋转,更逼真的演示现实的状况。计算角度需要知道坐标的具体值,命名变量x1,y1为preStone的坐标,x2,y2为curStone 的坐标,dx,dy分别为x2-x1,y2-y1,则dy/dx即为当前角度的tan(angle)的值,使用反正且函数便可以得出当前的角度,dx需要分为三种情况讨论,1,dx>0,则其角度应该在第一和第四象限,象限的概念是初中的知识,如果不明白的请再温习一下初中的教科书,反正切的值在-PI/2到PI/2之间,直接旋转既为正确答案,2.dx<0则其角度在第二和第三象限,需要在得到反正切之后再旋转180度得到,因此其值为atan(dy/dx)+PI,这样经过旋转之后便为正确答案,3,如果dx为零,则需要判断dy与零的关系,如果dy大于0,则需要旋转 PI/2,如果dy小于零,则需要旋转-PI/2,如果为0,则旋转角度可以为0;以上的分析逻辑可以得到如下的程序:
int x1, y1, x2, y2, dx, dy, steps;
                            x1 = preStone.getX();
                            y1 = preStone.getY();
                            x2 = curStone.getX();
                            y2 = curStone.getY();
                            dx = x2 - x1;
                            dy = y2 - y1;
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
                            double angle = 0;
                            if (dx > 0) {
                                   angle = Math.atan(dy * 1.0 / dx * 1.0);
                            } else if (dx < 0) {
                                   angle = Math.PI + Math.atan(dy * 1.0 / dx);
                            } else if (dx == 0) {
                                   if (dy >= 0) {
                                          angle = Math.PI / 2;
                                   } else {
                                          angle = Math.PI * 3 / 2;
                                   }
                            }
                            cartoon.setAngle(angle);
注意:在进行反正切的过程中整数相除必须转换为双精度相除,否则类似于30/33其结果为0,这就会使得精度大打折扣。
       得到了旋转的角度后,便需要在两点之间找出每次画图标所处的坐标。作者的思想是首先算出当前两点之间的距离L,循环由0到L根据步长遍历,利用相似三角形的原理和坐标平移的原理得到目前遍历的点的坐标,程序如下:
steps = (int) Math.round(Math.sqrt(dx * dx + dy * dy));
得到两点之间的总长度,即步长,
for (int i = 0; i <= steps; i += 3) {
//循环从0到总步长,每次增加三个步长。
                                   curX = (int) Math.round(x1 + 1.0 * dx * i / steps);
根据相似三角形的原理得到当前的x轴坐标
                                   curY = (int) Math.round(y1 + 1.0 * dy * i / steps);
根据相似三角形的原理得到当前的Y轴坐标
当所有的点已经准备好了,便可以刷新Jpanel了,JPanel的刷新会调用调用PaintComponent方法,paintComponent又会调用Route的画图方法,在route的画图方法中使用当前的设置画出图标,画图标的过程如下:得到图标的URL,根据URL得到ImageICon的图标,取出图标的高和宽度,克隆一个坐标系,对坐标系进行旋转,并把坐标系设置到Graphic,在相应位置的画出图标,使得图标的中心点在给定的x,y上,还原原来的graphic的坐标系。这样整个图标便画完了。实现代码如下:
URL url = getClass().getResource("/icon/" + getVehicle() + ".gif");
                     ImageIcon vIcon = new ImageIcon(url);
                     int height = vIcon.getIconHeight();
                     int width = vIcon.getIconWidth();
                     AffineTransform origXform = g.getTransform();
                     AffineTransform newXform = (AffineTransform) (origXform.clone());
                     int xRot = cartoon.getCurX();
                     int yRot = cartoon.getCurY();
                     newXform.rotate(cartoon.getAngle(), xRot, yRot);
                     g.setTransform(newXform);
                     g.drawImage(vIcon.getImage(), xRot - width / 2, yRot - height / 2,
                                   null);
                     g.setTransform(origXform);
以上为个人的实现方法,欢迎大家指正交流。
作者简介:凌辉 北京*******科技发展有限公司  软件开发部 项目经理,数据库方向研究生学历,设计开发过多个J2EE应用程序,有丰富的软件开发、管理、测试经验,擅长网站应用程序开发,在设计模式,软件重构,版本控制,软件保护,数据库设计与管理等方面都有独特的见解。
联系方式:QQ:21731278 msn:[email]lili00okok123@hotmail.com[/email]

转载于:https://blog.51cto.com/tianli/97749

GPS实时跟踪程序模拟(2)动画回放相关推荐

  1. GPS实时跟踪程序模拟

    由于GPS全球定位系统的发展,大部分的快递系统都使用了GPS以便于及时得知当前运送货品以及车辆的位置,并在地图上以直观的形式展示出来.具备这样功能的快递系统在市场中更具有竞争力.刚好公司的一个项目中使 ...

  2. 在Blender中制作火箭发射烟雾和火焰模拟的动画

    大小:1.25G 时长1h 30m 1280X720 MP4 语言:英语+中英文字幕(根据原英文字幕机译更准确) 在Blender中制作火箭发射烟雾和火焰模拟的动画 Animate a Rocket ...

  3. 用缓动函数模拟物理动画

    1.缓动函数简介 <1>缓动函数的动画效果是建立在CALayer层级的关键帧动画基础之上 也就是说用普通的UIView的Animation是无法直接实现缓动函数 <2>缓动函数 ...

  4. 使用GPS实时记录运动路线

    使用GPS实时记录运动路线,没有经过真机测试但是理论上应该没问题 等有流量后进行一下性能测试 主要思路就是使用list实时记录运动坐标 , 继承 Overlay,并重写draw方法,在draw方法中通 ...

  5. php 安卓实现实时导航,用安卓平板电脑轻松实现GPS实时导航

    [IT168 应用]不少朋友都在用Android(安卓)系统的平板电脑,除了上网冲浪.看电影.玩游戏,有些平板电脑还内置GPS功能或可以外接GPS模块,我们可利用平板电脑实现GPS实时导航.位置定位, ...

  6. 测试地图长度和高度软件,‎App Store 上的“海拔测量仪-集指南针和GPS实时高度测距仪二合一”...

    海拔测量仪是一款外出旅游.户外达人必备的APP,拥有非常强大和准确的GPS定位功能,让你以最快的速度准确实时的获取到当前位置的的海拔.GPS位置.气压.经纬度坐标等信息,并且还内置指南针功能,这将是您 ...

  7. HTML绘制齿轮,HTML5模拟齿轮动画代码实例

    HTML代码 css代码#level{ width:100%; height:1px; position:absolute; top:50%; } #content{ text-align:cente ...

  8. 高德地图实现Marker模拟gif动画

    两个方法: 1.markerOptions.icons(iconList);设置多张图模拟gif动画 2.markerOptions.period(1);值越小刷新的越快 注意事项: 如果显示了gif ...

  9. GPS实时定位、获取基站信息

    好久没有来更新我的博客了 , 最近刚做了一个GPS实时定位和获取基站信息的一个小的Demo ,这个辛酸泪啊- 来给大家们来分享一下 ! 做这个项目我用的是用的原始的手机GPS定位, 因为这个有可能需要 ...

最新文章

  1. 【Leetcode | 03】String
  2. c 的word转为html5,word与html互转(1) -- word转html
  3. 【原型设计】第五节:Axure RP9 交面交互的使用说明 02 显示隐藏元素
  4. 亚马逊无人超市Amazon Go这次是真的真的开业了
  5. JAVA card 应用开发(六) 个人化数据的线路安全和数据安全
  6. arm7 键盘扫描程序
  7. Amos实操教程|调节效应检验
  8. 目前最新传智播客郭永锋最新工作室2018Java培训项目实战(完整)
  9. 酒桌游戏c语言,必学的酒桌游戏,让你成为聚会中最亮的仔
  10. 拳皇重生服务器维护,《拳皇97 OL》7月7日更新维护公告
  11. STM32 解析 JSON 之 cJSON
  12. 手把手QQ机器人制作教程,根据官方接口进行开发,基于Python语言制作的详细教程(更新中)
  13. 找单身狗版本2(有两个单身狗)
  14. JavaScript——leetcode917. 仅仅反转字母
  15. JAVA编程-----猜姓氏游戏
  16. Veeam中的几种备份方式
  17. Symbian模拟器启动一会自动消失
  18. 螺旋节能灯和U型节能灯相比有哪些优点?
  19. linux f5作用,[Linux]F5负载均衡器
  20. windows phone7天气预报源代码

热门文章

  1. 阿里云Kubernetes实战2–搭建基础服务
  2. Mongodb aggregation 基本操作示例
  3. 浅析开源数据库MySQL架构
  4. ARM处理器:开放者的逆袭
  5. 【Spark Summit East 2017】Kerberizing Spark
  6. vb调用excel方法详解及操作相关操作命令大全
  7. 抽取、转换和装载介绍(八)实时的意义(待续)
  8. 在android上移植ios
  9. iOS和OS X中的bundle
  10. ORA-01081: cannot start already-running ORACLE - shut it down first