870920 Menu

Swing-Parking项目小结

Swing-Parking是一款运行于Linux Ubuntu,Windows x64和OSX 10.8以上平台的桌面单机小程序,用于车辆转弯、倒车及入库的教学演示、沙盘模拟和辅助训练。开发语言:C++ 11,类库:JUCE 4.2.3,IDE:Xcode 7.2 on OSX 10.10.5, VS 2015 on Windows 10。立项日期:2016年07月26日,第一阶段编码完工于2016年8月12日。

e8360b1d-a413-4d8a-8e9e-de9c7a507685

结构

  • CommonData.h:程序中所使用的静态常量。
  • Main.cpp:含定制的LookAndFeel(用于增大ToggleButton的字体大小,后并未使用),主程序类(嵌套主窗口类),启动宏。
  • MainComponent头源:工作区GUI类,含左侧的训练场/停车场,右侧的设置面板,右下角是隐现设置面板的按钮。
  • SetupPanel头源:设置面板,GUI类,构造参数为ParkingLot,用于直接控制车场区。因此本类也充当MVC结构中的模型和控制器。
  • ParkingLot头源:车场区,GUI类,本程序任务最重的类。含教练车、多台静止的车、车位。其中车位类是本类的private嵌套类。
  • TrainingCar头源:教练车,GUI类。
  • RestingCar头源:静止的车,GUI类。
  • MeasuringComp头源:测距时出现并随鼠标拖拽而实时变化的标线和标注,GUI类。

备注

  • AffineTransform类旋转组件、线条的使用。比如:基于当前转向角度下的转向圆圆心,移动教练车时,对其进行旋转。每移动(前进/后退)一次,弧度增大或减少一个固定值。旋转半径实则车辆在当前转向角下的最小转弯半径。代码示例:

  • 组件paint()方法中绘制Path轨迹(将车轮轨迹绘制成线条):

  • 灵活使用辅助对象进行可视元素的复杂定位。比如:可使用不可视的组件或Point点。本程序的重大难点就是用这种思路解决的。该难点是:车辆经过复杂转弯和直行后,再次转弯,即角度变换(特别是左转变右转,或反之),转向圆的圆心,即仿射变换的旋转中心点改变,如何定位这个旋转中心点颇费了一番功夫。解决策略是:
    • 定位新的旋转中心点。基于当前的旋转中心点和车辆的仿射变换弧度,以及转弯半径(基于新转向角度和方向),得出对车身进行旋转的中心点,即转弯圆心(因为圆心始终位于后轴延长线的某处)。
    • 定位车辆并旋转之。用定位后的中心点(转弯圆心、仿射变换的中心点)对车辆进行定位,而后仿射变换。此时仿射变换的旋转弧度是不变的,只要不再转弯状态下行驶车辆,旋转弧度就不变。而任何车身偏转的状态下直行,都不改变旋转弧度。

  • 测距功能的实现,操作模式为:鼠标在界面中某处单击并拖动,实时出现一条标线(paint()中绘制的线条)和距离显示(Label对象实时改变所显示的文本),鼠标单击的位置为标线的起点,松开鼠标按键的位置为标线的结束点。实现策略:鼠标单击是创建测距组件,并确定开始点。所创建的对象添加到一个OwnedArray自有数组中(位于最后)。拖拽和释放鼠标按键,则实时改变测距组件的大小(通过设置其结束点位置)。

  • 每次移动车辆之后的出界、碰撞检测和入位是否成功的检测,实现思路:每次移动后,对教练车的车身四边取一批点,逐个点检测是否位于给定组件(出界检测则是父组件不包含某个车身点)。

其它

  • 车辆转弯半径的计算公式遵循正弦定理:r = 轴距 / sin (α)
  • 上述公式中的α为外侧前轮的转向角。当转向角达到最大时,计算结果为车辆的最小转弯半径。普通汽车的前轮外侧最大转向角在32-35度之间。
  • 上述公式计算结果为转弯圆心到外侧前轮的触地中心点的距离,实际车辆的转弯半径还要加上车轮触地点到车头左/右顶点的距离(弧高)。通常,一般车辆的最小转弯半径为轴距的两倍。本程序中,教练车的轴距2.8米,外侧前轮的最大转向角33度,最小转弯半径5.6米。
  • 标准库sin()函数的参数为弧度。JUCE类库中,凡与三角函数有关的方法,其参数一律为弧度。0度为钟表12点位置,顺时针为弧度增大,逆时针则为弧度减小。2π转一圈(360度)。
    角度转弧度:radian = angle / 180 * π
    弧度转角度:angle = radian * 180 / π