博客统计信息

51cto博客之星
用户名:lili00okok
文章数:108
评论数:266
访问量:298301
无忧币:2995
博客积分:4120
博客等级:7
注册日期:2007-06-27

GPS实时跟踪程序模拟(2)动画回放
2008-09-07 19:15:41
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://tianli.blog.51cto.com/190322/97749
上一篇文章介绍了实时跟踪程序中画点的操作,在这里介绍如果实现程序跟踪的动画回放。实现动画回放的基本原理是不停的刷新JPanel,在每次刷新的过程中,把图片画在相邻的位置便可以实现动画的效果。
       为了实现动画的回放,需要使用Thread进行不停的刷新。回顾一下线路数据结构:线路的ID,线路的名称,线路的所有点的集合,线路的图片名称,线路的交通工具,为了实现动画,还需要为线路添加一个记录动画位置的类,命名为Cartoon,Cartoon类包含了当前动画位置的curX,curY 坐标,当前倾斜的角度angle,在画JPanelpainComponent方法中调用路线的画图方法,便可以画出线路,Route类需要遍历每个Stone点,对于每个点调用点的画图方法,之后再根据点的先后画出两个点之间的连线,在连线也画好的情况下再根据Cartoon的坐标和旋转角度画出相应的交通工具,这就是线路画图的所有步骤。另外在必要的情况下开启一个线程,线程拥有指向JPanel的句柄,从JPanel中获取线路的句柄,再从线路的句柄中获取Cartoon的句柄,线程便可以根据线路中的两个点计算刷新时图片的位置,线程休眠一段时间,再次计算图片的位置,调用JPanel进行刷新,反复执行,便可以得到动画。在这个过程中,线程的开始可以由事件触发,线程的结束可以根据当前线路是否已经到达最后来作为退出条件,或者被中断。
       假设目前动画需要走的线段由两个点决定,比如preStone,前一个点,curStone当前点。图标需要从preStone走到curStone,首先需要计算出目前行进的角度,确定角度的目的是使得图标做出相应的旋转,更逼真的演示现实的状况。计算角度需要知道坐标的具体值,命名变量x1,y1preStone的坐标,x2,y2curStone 的坐标,dxdy分别为x2-x1,y2-y1,则dy/dx即为当前角度的tan(angle)的值,使用反正且函数便可以得出当前的角度,dx需要分为三种情况讨论,1dx>0,则其角度应该在第一和第四象限,象限的概念是初中的知识,如果不明白的请再温习一下初中的教科书,反正切的值在-PI/2PI/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;
 
                            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,循环由0L根据步长遍历,利用相似三角形的原理和坐标平移的原理得到目前遍历的点的坐标,程序如下:
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应用程序,有丰富的软件开发、管理、测试经验,擅长网站应用程序开发,在设计模式,软件重构,版本控制,软件保护,数据库设计与管理等方面都有独特的见解。
联系方式:QQ21731278 msnlili00okok123@hotmail.com

本文出自 “凌辉” 博客,请务必保留此出处http://tianli.blog.51cto.com/190322/97749

分享至
更多
一键收藏,随时查看,分享好友!
0人
了这篇文章
类别:java技术技术圈()┆阅读()┆评论() ┆ 推送到技术圈返回首页

文章评论

 
2008-09-08 21:15:20
算法之与程序,正如骨骼之与血肉

2008-09-09 11:01:50
算法是程序的基础。

2010-06-04 09:23:22
3S人网站

3S人网站(www.3sren.com):通过与行业资深企业及专家合作打造庞大、领先的3S行业产品及技术资源库,为企业与高黏度的用户群建设一个高效、专业的增值服务平台。

3S人的特色(www.3sren.com)

丰富的行业资源(http://www.3sren.com/zt/)

3S人的隆重上线,得到了行业协会、各会员单位、合作伙伴等。如国土资源部土地整理中心、灵图、数慧、中软等业界的大力支持与关注。

 
敏锐的行业分析(http://www.3sren.com/zt/)

3S人通过与行业资深企业及专家合作打造庞大、领先的3S行业产品及技术库,及时敏锐地进行行业分析,推动整个产业朝着积极、健康的方向发展。

 
及时的产品发布(http://www.3sren.com/zt/)

这几年,数字城市的推广,GPS,网络地图等软件及产品的发展,庞大的用户市场格局正在逐步展现,企业将会越来越注重品牌及产品的宣传,我们会在第一时间发布企业的产品与推广。

 
公正的第三方评测(http://www.3sren.com/zt/)

3S始终坚持中立、公正、客观的立场对产品、技术进行权威的评测,通过各种分析为企业及用户提供实用、有效的参考。.


开放的产品应用平台(http://www.3sren.com/zt/)

通过各种手段,我们将建立多种应用平台,譬如与企业或培训机构合作的网络模式,为企业节约人才培养成本及风险,为用户提供方便。

3S人网站:www.3sren.com



 

发表评论            

【技术门诊】专家解析:软考重点难点及应试技巧
昵  称:
登录  快速注册
验证码:

请点击后输入验证码博客过2级,无需填写验证码

内  容: