项目的要求很简单:

  模拟出十字路口的交通控制情况;

  考虑东、西、南、北四个方向,每条路分为两个车道,每个路口设置一盏显示灯。为简单起见, 每种灯显示时间为8秒。

  当东西(或南北)方向红灯时,所有车辆(除了消防车、救护车、警车)均排队等待,当东西(或南北)方向绿灯时,所有车辆按序行驶(不准超车)。

制作这个小框体程序我选择的平台是JAVA,实现结果效果图如下所示:

  首先分析整个项目题目上的要求,在十字路口上通过的车辆可以抽象为两类:普通车辆和特殊车辆(包括警车,消防车,救护车等),所谓普通的车辆和特殊种类的车辆之间的差别是是否需要在红绿灯路口之前进行等待操作,特殊车辆享有优先权并且可以直接通过路口,而普通的车辆必须严格遵守交通规则。

由于整个题目的环境假定为交通十字路口,那么有如下几个隐式的条件要求:

(1)不失一般性的,任意车辆在前方有车辆在等待的情况下必须也进行等待操作。

(2)车辆与车辆之间无论是正面还是侧面之间都不允许发生碰撞且最好保持一个“安全距离”,换句话讲,一个严格的要求是车辆之间不允许发生重叠。

(3)红绿灯按照一个既定的规律进行变换,控制普通车辆的行进与停止

(4)车辆的次序或者方向要实现随机分配,即整个路口可以处理各种车辆位置的情况

在这个项目之中我们不妨假设车辆的行进路径只有单方向,即不会出现车辆转弯的状况,这样一来就大大简化了整个项目的难度。所以因为所有车辆都是直行,所以在整个十字路口的范围内我们需要一定数量的信号来处理路口内部车辆行进的分配问题,其次是红绿灯的分配也需要一个信号量来处理车辆和红绿灯变换之间的关系。

如右图所示,MyMutex.center是表示整个十字路口正中央的信号辆所代表的位置,东西南北是个方向分别在这个信号量表示中为上下左右四个方向,每个方向有4条道路,其中的道路两两并行,每组方向相反。举个具体的例子就是(车辆靠右侧通行)北(上)边最右侧的车道驶来的车辆与西(左)边最左侧的车道驶来的车辆可能会在图中的MyMutex.center[0][0]处相遇,在相遇的同时只有一辆车辆允许通行,若已经有车辆通过该交汇处,那么已经进入并且占有信号量的车

辆优先通过,反之亦然。

在上述的条件的约束之下,我们决定使用可视化界面来实现整个十字路口车辆分配的问题。

不妨把车辆抽象成为矩形,利用java.awt库下的类做出两个模拟的车辆的模样,分别代表特殊车辆和普通车辆。(特殊车辆一律用警车图案来概括)

那么车辆行驶的过程就是车辆图案的平移过程,经过草图设计我们暂定车辆LOGO的大小为30*50(道路的宽度为50)也就是说会在车辆的两侧个留出10pixel的矩形作为所谓安全距离,整个车辆的平移的过程经过测试评估最终确定为每0.2s移动10像素,会留下较好的动画效果和观察准度。

接下来是实现整个界面底层的环节:

(1)所有车辆模型的实质是java.awt库内的矩形和线条,车辆模型的移动的实质就是线条和矩形的移动过程,但是在移动的过程之中,首先需要图案进行旋转处理以使之对应东西走向上的车辆,为了避免反复重复计算出每个线条的位置,我们做出8个容器来存储每个方向上每个车道上的车辆初始线条位置,从次之后的每次绘制只需要在容器中取出每个线条再对之进行比较简单的平移操作即可。

(2)我们整个界面的动画是通过不断调用JComponent类的repaint()方法来实现的,所以我们首先需要重写paint()方法,从P/V操作的角度考虑,对于每一条路径上的车辆可能会处理的情况如下所示:

(3)整个界面的宏观角度来看,整个程序的流程过程图如下所示:

(4)根据上述设计,个人感觉java中的synchronized关键字不太适合这个项目,因为直接使用synchronized很有使得两个同时相碰的车辆发生死锁现象,所以我的解决方法是根据java代码执行的特点,将八个线程的运行run() 函数内容直接依次排序,实质上是相当于给八个线程设定了默认的优先级这样一来就解决了死锁的现象。

代码分享: ## 由于作业Deadline还没有到我就先发布一些关键的绘制部分的代码块,等到Deadline一过就把源码全部展示出来 ##

(1)paint()函数重载后的写法

    public void paint(Graphics g){
super.paint(g);
Graphics2D g2=(Graphics2D)g;
/////Traffic Lights
g2.setPaint(Color.black);
g2.fill(signalpane);
g2.setPaint(Color.red.darker());
g2.fill(redsignal);
g2.setPaint(Color.green.darker());
g2.fill(greensignal); /////PaintRoad
g2.setPaint(Color.gray.brighter());
Rectangle2D roadh=new Rectangle2D.Float(250,0,200,700);
Rectangle2D roadv=new Rectangle2D.Float(0,250,700,200);
g2.fill(roadh);
g2.fill(roadv); ///// /////Graphics Defination
g2.setPaint(Color.black);
g.drawLine(250, 0, 250, 700);
g.drawLine(350, 0, 350, 700);
g.drawLine(450, 0, 450, 700);
g.drawLine(0, 250, 700, 250);
g.drawLine(0, 350, 700, 350);
g.drawLine(0,450,700, 450);
g2.setPaint(Color.gray.darker());
g.drawLine(300,0,300,700);
g.drawLine(400,0,400,700);
g.drawLine(0,300,700,300);
g.drawLine(0,400,700,400);
Rectangle2D centerroad=new Rectangle2D.Float(250,250,200,200);
///////////////////////Road Drawing
///////////////////////Color can be attached
g2.setPaint(Color.gray.brighter());
g2.fill(centerroad);
g2.setPaint(Color.black);
g2.draw(centerroad);
////////////////////////Specail Car Outline painting
////////////////////////Located from 500,20 size 30,50
///////////////////////Combined by llright,rlight,specialCarOut,specialCarIn,specialCarLightLeft,specialCarLightRight
g2.fill(specialCarOut);
g2.setPaint(Color.gray);
g2.draw(specialCarLightLeft);
g2.draw(specialCarLightRight);
g2.draw(specialCarOut);
g2.setPaint(Color.white);
g2.fill(specialCarIn);
g2.setPaint(Color.red);
g2.fill(specialCarLightLeft);
g2.setPaint(Color.blue);
g2.fill(specialCarLightRight);
g2.setPaint(Color.yellow);
g2.fill(sllight);
g2.fill(srlight);
//////////////////////////////////////Normal Car Outline Painting
//////////////////////////////////////Located from 550,20 size 30,50 g2.setPaint(Color.gray);
g2.draw(normalCarIn);
g2.draw(normalCarOut);
g2.setPaint(Color.red);
g2.fill(normalCarOut);
g2.setPaint(Color.magenta);
g2.fill(normalCarIn);
g2.setPaint(Color.yellow);
g2.fill(nllight);
g2.fill(nrlight);
//////////////////
/////////////////Painting Finished
/////////////////For switch to change
if(bLight==true){
g2.setPaint(Color.green.brighter());
g2.fill(greensignal);
g2.setPaint(Color.black);
g2.fill(redsignal);
}else{
g2.setPaint(Color.black);
g2.fill(greensignal);
g2.setPaint(Color.red.brighter());
g2.fill(redsignal);
} ////Testing Field ////nn
Iterator iter=northCars.iterator();
while(iter.hasNext()){
Car c=(Car)iter.next();
paintCar(g2,c);
}
////sn
iter=snorthCars.iterator();
while(iter.hasNext()){
Car c=(Car)iter.next();
paintCar(g2,c);
}
////ns
iter=southCars.iterator();
while(iter.hasNext()){
Car c=(Car)iter.next();
paintCar(g2,c);
}
////ss
iter=ssouthCars.iterator();
while(iter.hasNext()){
Car c=(Car)iter.next();
paintCar(g2,c);
}
///ne
iter=eastCars.iterator();
while(iter.hasNext()){
Car c=(Car)iter.next();
paintCar(g2,c);
}
////se
iter=seastCars.iterator();
while(iter.hasNext()){
Car c=(Car)iter.next();
paintCar(g2,c);
}
/////nw
iter=westCars.iterator();
while(iter.hasNext()){
Car c=(Car)iter.next();
paintCar(g2,c);
}
////sw
iter=swestCars.iterator();
while(iter.hasNext()){
Car c=(Car)iter.next();
paintCar(g2,c);
}
///////////////////Testtttting!!!!!! ///////////////////
}

(2)线条/图案容器

public static Vector<Car> northCars=new Vector<>();
public static Vector<Car> southCars=new Vector<>();
public static Vector<Car> eastCars=new Vector<>();
public static Vector<Car> westCars=new Vector<>();
public static Vector<Car> snorthCars=new Vector<>();
public static Vector<Car> ssouthCars=new Vector<>();
public static Vector<Car> seastCars=new Vector<>();
public static Vector<Car> swestCars=new Vector<>();
public static boolean bLight=true;

(3)车辆坐标容器

    protected static Vector<Shape> northshape=new Vector<>();
protected static Vector<Shape> southshape=new Vector<>();
protected static Vector<Shape> eastshape=new Vector<>();
protected static Vector<Shape> westshape=new Vector<>();
protected static Vector<Shape> snorthshape=new Vector<>();
protected static Vector<Shape> ssouthshape=new Vector<>();
protected static Vector<Shape> seastshape=new Vector<>();
protected static Vector<Shape> swestshape=new Vector<>();

(4)actionPerformed接口方法实现

    public void actionPerformed(ActionEvent e){
Object source=e.getSource();
if(source==timer){
Iterator it;
////nn
it=northCars.iterator();
while(it.hasNext()){
Car car=(Car)it.next();
if(car.y==700)it.remove();
if(car.y==250){
if(bLight==true)continue;///Stop
//}else if(car.y==250){
if(MyMutex.center[0][0]==0)MyMutex.center[0][0]--;else continue;///Stop
}else if(car.y==340){
MyMutex.center[0][0]++;
}else if(car.y==300){
if(MyMutex.center[1][0]==0)MyMutex.center[1][0]--;else continue;///Stop
}else if(car.y==390){
MyMutex.center[1][0]++;
}else if(car.y==350){
if(MyMutex.center[2][0]==0)MyMutex.center[2][0]--;else continue;
}else if(car.y==440){
MyMutex.center[2][0]++;
}else if(car.y==400){
if(MyMutex.center[3][0]==0)MyMutex.center[3][0]--;else continue;
}else if(car.y==490){
MyMutex.center[3][0]++;
}
car.y+=10;
}
///////ns
it=snorthCars.iterator();
while(it.hasNext()){
Car car=(Car)it.next();
if(car.y==700)it.remove();
if(car.y==250){
//if(bLight==true)continue;///Stop
//}else if(car.y==250){
if(MyMutex.center[0][1]==0)MyMutex.center[0][1]--;else continue;///Stop
}else if(car.y==340){
MyMutex.center[0][1]++;
}else if(car.y==300){
if(MyMutex.center[1][1]==0)MyMutex.center[1][1]--;else continue;///Stop
}else if(car.y==390){
MyMutex.center[1][1]++;
}else if(car.y==350){
if(MyMutex.center[2][1]==0)MyMutex.center[2][1]--;else continue;
}else if(car.y==440){
MyMutex.center[2][1]++;
}else if(car.y==400){
if(MyMutex.center[3][1]==0)MyMutex.center[3][1]--;else continue;
}else if(car.y==490){
MyMutex.center[3][1]++;
}
car.y+=10;
}
/////sn
it=southCars.iterator();
while(it.hasNext()){
Car car=(Car)it.next();
if(car.y==0)it.remove();
if(car.y==450){
if(bLight==true)continue;///Stop
//}else if(car.y==450){
if(MyMutex.center[3][3]==0)MyMutex.center[3][3]--;else continue;///Stop
}else if(car.y==360){
MyMutex.center[3][3]++;
}else if(car.y==400){
if(MyMutex.center[2][3]==0)MyMutex.center[2][3]--;else continue;///Stop
}else if(car.y==310){
MyMutex.center[2][3]++;
}else if(car.y==350){
if(MyMutex.center[1][3]==0)MyMutex.center[1][3]--;else continue;
}else if(car.y==260){
MyMutex.center[1][3]++;
}else if(car.y==300){
if(MyMutex.center[0][3]==0)MyMutex.center[0][3]--;else continue;
}else if(car.y==210){
MyMutex.center[0][3]++;
}
car.y-=10;
}
////ss
it=ssouthCars.iterator();
while(it.hasNext()){
Car car=(Car)it.next();
if(car.y==0)it.remove();
if(car.y==450){
//if(bLight==true)continue;///Stop
//}else if(car.y==450){
if(MyMutex.center[3][2]==0)MyMutex.center[3][2]--;else continue;///Stop
}else if(car.y==360){
MyMutex.center[3][2]++;
}else if(car.y==400){
if(MyMutex.center[2][2]==0)MyMutex.center[2][2]--;else continue;///Stop
}else if(car.y==310){
MyMutex.center[2][2]++;
}else if(car.y==350){
if(MyMutex.center[1][2]==0)MyMutex.center[1][2]--;else continue;
}else if(car.y==260){
MyMutex.center[1][2]++;
}else if(car.y==300){
if(MyMutex.center[0][2]==0)MyMutex.center[0][2]--;else continue;
}else if(car.y==210){
MyMutex.center[0][2]++;
}
car.y-=10;
}
///ne
it=eastCars.iterator();
while(it.hasNext()){
Car car=(Car)it.next();
if(car.x==0)it.remove();
if(car.x==450){
if(bLight==false)continue;///Stop
//}else if(car.x==450){
if(MyMutex.center[0][3]==0)MyMutex.center[0][3]--;else continue;///Stop
}else if(car.x==360){
MyMutex.center[0][3]++;
}else if(car.x==400){
if(MyMutex.center[0][2]==0)MyMutex.center[0][2]--;else continue;///Stop
}else if(car.x==310){
MyMutex.center[0][2]++;
}else if(car.x==350){
if(MyMutex.center[0][1]==0)MyMutex.center[0][1]--;else continue;
}else if(car.x==260){
MyMutex.center[0][1]++;
}else if(car.x==300){
if(MyMutex.center[0][0]==0)MyMutex.center[0][0]--;else continue;
}else if(car.x==210){
MyMutex.center[0][0]++;
}
car.x-=10;
}
//se
it=seastCars.iterator();
while(it.hasNext()){
Car car=(Car)it.next();
if(car.x==0)it.remove();
if(car.x==450){
//if(bLight==false)continue;///Stop
//}else if(car.x==450){
if(MyMutex.center[1][3]==0)MyMutex.center[1][3]--;else continue;///Stop
}else if(car.x==360){
MyMutex.center[1][3]++;
}else if(car.x==400){
if(MyMutex.center[1][2]==0)MyMutex.center[1][2]--;else continue;///Stop
}else if(car.x==310){
MyMutex.center[1][2]++;
}else if(car.x==350){
if(MyMutex.center[1][1]==0)MyMutex.center[1][1]--;else continue;
}else if(car.x==260){
MyMutex.center[1][1]++;
}else if(car.x==300){
if(MyMutex.center[1][0]==0)MyMutex.center[1][0]--;else continue;
}else if(car.x==210){
MyMutex.center[1][0]++;
}
car.x-=10;
}
//nw
it=westCars.iterator();
while(it.hasNext()){
Car car=(Car)it.next();
if(car.x==700)it.remove();
if(car.x==250){
if(bLight==false)continue;///Stop
//}else if(car.x==250){
if(MyMutex.center[3][0]==0)MyMutex.center[3][0]--;else continue;///Stop
}else if(car.x==340){
MyMutex.center[3][0]++;
}else if(car.x==300){
if(MyMutex.center[3][1]==0)MyMutex.center[3][1]--;else continue;///Stop
}else if(car.x==390){
MyMutex.center[3][1]++;
}else if(car.x==350){
if(MyMutex.center[3][2]==0)MyMutex.center[3][2]--;else continue;
}else if(car.x==440){
MyMutex.center[3][2]++;
}else if(car.x==400){
if(MyMutex.center[3][3]==0)MyMutex.center[3][3]--;else continue;
}else if(car.x==490){
MyMutex.center[3][3]++;
}
car.x+=10;
}
///sw
it=swestCars.iterator();
while(it.hasNext()){
Car car=(Car)it.next();
if(car.x==700)it.remove();
if(car.x==250){
//if(bLight==false)continue;///Stop
//}else if(car.x==250){
if(MyMutex.center[2][0]==0)MyMutex.center[2][0]--;else continue;///Stop
}else if(car.x==340){
MyMutex.center[2][0]++;
}else if(car.x==300){
if(MyMutex.center[2][1]==0)MyMutex.center[2][1]--;else continue;///Stop
}else if(car.x==390){
MyMutex.center[2][1]++;
}else if(car.x==350){
if(MyMutex.center[2][2]==0)MyMutex.center[2][2]--;else continue;
}else if(car.x==440){
MyMutex.center[2][2]++;
}else if(car.x==400){
if(MyMutex.center[2][3]==0)MyMutex.center[2][3]--;else continue;
}else if(car.x==490){
MyMutex.center[2][3]++;
}
car.x+=10;
}
adjust();
repaint();
}else if(source==timerLight){
bLight=!bLight;
if(bLight)hint.setText("Now Right-Left Road is Accessible!");
else hint.setText("Now Up-Down Road is Accessible!");
}else if(source==testTimer){
//northCars.add(new Car(0,0,260,50));
//snorthCars.add(new Car(0,1,310,50));
//southCars.add(new Car(1,0,440,650));
//ssouthCars.add(new Car(1,1,410,650));
//eastCars.add(new Car(2,0,650,260));
//seastCars.add(new Car(2,1,650,310));
//westCars.add(new Car(3,0,50,440));
//swestCars.add(new Car(3,1,50,410));
}else if(source==westn){
westCars.add(new Car(3,0,50,440));
}else if(source==wests){
swestCars.add(new Car(3,1,50,410));
}else if(source==eastn){
eastCars.add(new Car(2,0,650,260));
}else if(source==easts){
seastCars.add(new Car(2,1,650,310));
}else if(source==northn){
northCars.add(new Car(0,0,260,50));
}else if(source==norths){
snorthCars.add(new Car(0,1,310,50));
}else if(source==southn){
southCars.add(new Car(1,0,440,650));
}else if(source==souths){
ssouthCars.add(new Car(1,1,410,650));
} /////Swtich Table For Source Handling }

Tips:如果有任何问题欢迎联系我或者留下评论

<JAVA图像学习笔记>十字路口交通模拟--操作系统模拟课后小项目的更多相关文章

  1. <JAVA图像学习笔记>关于Graphics/Graphics2D以及简单的几何图像制作(一个简单钟表的实现)

    题外话:正好赶上OperatingSystem的作业要做一个模拟线程/进程调度的问题,决定用JAVA实现才发现这些内容和之前学过的GUI制作是两码事儿- -b 通过学习java.swing库的Acti ...

  2. [原创]java WEB学习笔记66:Struts2 学习之路--Struts的CRUD操作( 查看 / 删除/ 添加) 使用 paramsPrepareParamsStack 重构代码 ,PrepareInterceptor拦截器,paramsPrepareParamsStack 拦截器栈

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  3. Android(java)学习笔记167:Java中操作文件的类介绍(File + IO流)

    1.File类:对硬盘上的文件和目录进行操作的类.    File类是文件和目录路径名抽象表现形式  构造函数:        1) File(String pathname)       Creat ...

  4. Android(java)学习笔记110:Java中操作文件的类介绍(File + IO流)

    1.File类:对硬盘上的文件和目录进行操作的类.    File类是文件和目录路径名抽象表现形式  构造函数:        1) File(String pathname)       Creat ...

  5. java多线程学习笔记——详细

    一.线程类  1.新建状态(New):新创建了一个线程对象.        2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...

  6. Android(java)学习笔记233: 远程服务的应用场景(移动支付案例)

    一. 移动支付:       用户需要在移动终端提交账号.密码以及金额等数据 到 远端服务器.然后远端服务器匹配这些信息,进行逻辑判断,进而完成交易,返回交易成功或失败的信息给移动终端.用户提交账号. ...

  7. Java IO学习笔记二

    Java IO学习笔记二 流的概念 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成. 程序中的输入输 ...

  8. Android(java)学习笔记176: 远程服务的应用场景(移动支付案例)

    一. 移动支付:       用户需要在移动终端提交账号.密码以及金额等数据 到 远端服务器.然后远端服务器匹配这些信息,进行逻辑判断,进而完成交易,返回交易成功或失败的信息给移动终端.用户提交账号. ...

  9. 尚学堂JAVA基础学习笔记

    目录 尚学堂JAVA基础学习笔记 写在前面 第1章 JAVA入门 第2章 数据类型和运算符 第3章 控制语句 第4章 Java面向对象基础 1. 面向对象基础 2. 面向对象的内存分析 3. 构造方法 ...

随机推荐

  1. 对数据进行GZIP压缩和解压

    public class GzipUtils { /** * 对字符串进行gzip压缩 * @param data * @return * @throws IOException */ public ...

  2. 我是如何通过一个 XSS 探测搜狐内网扫描内网并且蠕动前台到最后被发现的

    我是如何通过一个 XSS 探测搜狐内网扫描内网并且蠕动前台到最后被发现的!(附带各种 POC) | WooYun-2014-76685 | WooYun.orghttp://wooyun.org/bu ...

  3. Jackson.jar的使用记录

    Jackson.jar的使用记录 之前一直使用json-lib.jar,近期发现网上说这个jackson.jar比較好 package com.spring.controller; import ja ...

  4. vuex 中关于 mapGetters 的作用

    mapGetters 工具函数会将 store 中的 getter 映射到局部计算属性中.它的功能和 mapState 非常类似,我们来直接看它的实现: export function mapGett ...

  5. canvas图片压缩,局部放大,像素处理

    直接上代码:(具体看注释) 需要引用jquery.min.js <!DOCTYPE html> <html lang="en"> <head> ...

  6. 为电脑添加u盘写保护

    需求:解决在公共打印PC机上u盘病毒的传染,设置后该PC机将不能对u盘文件进行写操作 修改注册表,在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Contro ...

  7. 设置windows时间开机同步方法

    本作品由Man_华创作,采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可.基于http://www.cnblogs.com/manhua/上的作品创作. 适用场景: 主板电池 ...

  8. 超出用省略号function()

    //判断是否微信浏览器 function isWeiXin() { var ua = window.navigator.userAgent.toLowerCase(); if (ua.match(/M ...

  9. web前端的一些实用技能

    如今我们使用的互联网,客户端与服务器端的交互无时无刻不在发生.比如我们在浏览器打开网页,浏览器就是客户端,将网页数据发过来的也就是服务器.其实服务器,并没有什么特别的,也就是一台昼夜不停运转的电脑罢了 ...

  10. C# MVC VS WebAPI

    获取路径: MVC:Server.MapPath("/Templates/vshop/default.json") WebAPI:System.Web.Hosting.Hostin ...