原项目代码分析
毕业设计交通仿真项目的遗留代码,按类难度从低到高捋一遍结构,方便后面改算法或换数据结构。
原项目代码类图

整体是「点 → 路 → 车 → 灯」层层叠:Point 表坐标,Road 连两点并管车辆队列和密度,再往上还有 Vehicle、TrafficLight、BitMatrix 等(类图里能看到关系)。
各类文件解析(按难度排序)
- Point (坐标类,使用经度,维度用来表示一个点)
最底层,只存经纬度,重载 == 判断是否为同一点(仿真里合并交叉口、去重用)。

Point.h
#pragma once
class Point {
public:
Point(double longitude, double latitdue);
bool operator == (Point & point);
private:
double longitude; //经度
double latitude; //纬度
};
注意头文件参数拼写是 latitdue,实现文件要一致,否则链接期才暴雷。
- Road (道路类,使用两个点来表示一条道路)
Road 在构造时用球面公式算两点间长度(R、PI 宏),并维护车道数、车辆 list、交通灯状态。countVehicleDensity 用「车辆数 / (路长 × 车道数)」,countCrowdExtent 按分段公式算拥挤度,供红绿灯或路径决策用。

Road.h
#pragma once
#include "stdafx.h"
#include "Point.h"
#include "Vehicle.h"
#include "TrafficLight.h"
#include "BitMatrix.h"
#define R 6378 //地球的平均半径
#define PI 3.14
#define LANE_AMOUNT 3 //每条道路的车道数量
#define MIN_VEHICLE 10 //初始状态每条道路的最少车辆
#define VEHICLE_SIZE 70
class Vehicle;
class TrafficLight;
class Road {
public:
Road(double longitude1, double latitude1, double longitude2, double latitude2): point1(longitude1, latitude1), point2(longitude2, latitude2) {
length = R * 2 * asin(sqrt(pow(sin((latitude1 / 180 * PI - latitude2 / 180 * PI) / 2), 2) + cos(latitude1 / 180 * PI) * cos(latitude2 / 180 * PI) * pow(sin((longitude1 / 180 * PI - longitude2 / 180 * PI) / 2), 2))); //计算道路长度
}
bool operator == (Road & road); //用于判断两条道路是否相连
double countVehicleDensity(void); //计算行车密度,行车密度 = 车辆数 / (道路长度 * 车道数)
double countCrowdExtent(void); //计算道路拥挤度
double returnLength(void); //返回道路长度
bool enterVehicle(void); //当前道路是否能进车
void updateVehicle(vector < Road > & road); //更新当前道路的车辆
void creatVehicle(int roadSize, int totalRoadSize, BitMatrix & roadBitMatrix, vector < Road > & road); //为该道路生成车辆
void enterVehicle(Vehicle & vehicle); //进入车辆
void updateTrafficLight(void); //更新当前道路的交通灯
/* 计算拥挤度的公式: crowdExtent = 0.15 * exp(-0.0322 * vehicleDensity) - 0.15 (vehicleDensity <= 45.5) crowdExtent = 0.111 * vehicleDensity - 0.0152 (vehicleDensity > 45.5) */
vector < int > adjoin; //存储相连的道路编号 是否改成private?
private:
Point point1, point2; //道路的两个端点的经纬度
double length, vehicleDensity, crowdExtent; //length为道路的长度,vehicleDensity为行车密度,crowdExtent为道路拥挤度
list < Vehicle > vehicle; //当前道路的车辆表
TrafficLight trafficLight; //交通灯用于控制车辆进入该道路
int vehicleSize; //当前道路车辆数
};
分析与思考:存储相连采用向量方式?这样真的好吗?一条条道路判断相等再连接?
adjoin 用 vector<int> 存邻接道路编号,构建图时要 O(n²) 两两 operator== 判相连,路多了会慢;若改成显式邻接表或建图阶段预处理坐标/网格索引,会好维护得多。vehicle 用 list 适合频繁进出,enterVehicle / updateVehicle 和 TrafficLight 的协作是仿真核心,读实现时建议对着类图从 creatVehicle 跟一条完整路径。
版权声明: 本文首发于 指尖魔法屋-原项目代码分析(https://blog.thinkmoon.cn/post/522-notes-cplusplus/) 转载或引用必须申明原指尖魔法屋来源及源地址!