Unity实现汽车前后轮倒车轨迹计算

汽车前后轮倒车轨迹计算附C#源码(Unity),供大家参考,具体内容如下

原理很简单, 都是高中的几何数学部分

需要的参数有:

  • 车前后轴距;
  • 车宽(左前轮与右前轮距离);
  • 当前车轮角度(多数车33.5°);
  • 是否要绘制前轮轨迹线;
///<summary>
/// 获取行车轨迹预测index = 0 left轨迹
/// </summary>
/// <param name="steeringAngle">方向盘角度</param>
/// <param name="carWheelbase">汽车前后轴距</param>
/// <param name="carWidth">车宽</param>
/// <param name="length">点位密度</param>
/// <param name="isFront">是否是前轮</param>
/// <param name="maxAngle">轨迹的最大转弯角度</param>
/// <returns>交叉数组,下标为0的是右边线, 下表为1的是左边线</returns>
public Vector3[][] GetCarTrack(float steeringAngle, float carWheelbase, float carWidth, float length, bool isFront, float maxAngle = 90f)
        {
            float maxSteerAngle = _carControl._vehicleController.steering.maxSteerAngle;
            float theta = Mathf.Abs(steeringAngle / 180 * Mathf.PI);
            Vector3[][] track = new Vector3[2][];
            List<Vector3> trackLeft = new List<Vector3>();
            List<Vector3> trackRight = new List<Vector3>();
            if (theta == 0)
            {
                for (float i = 0; i < length; i++)
                {
                    float x = i / length * 5;
                    if (isFront)
                    {
                        x *= 1;
                        trackLeft.Add(new Vector3(x, 0f, carWidth));
                        trackRight.Add(new Vector3(x, 0f, 0f));
                    }
                    else
                    {
                        x *= -1;
                        trackLeft.Add(new Vector3(x, 0, carWidth));
                        trackRight.Add(new Vector3(x, 0, 0));
                    }
                }
            }
            else
            {
                if (isFront)
                {
                    float r = (carWheelbase / Mathf.Tan(theta) + carWidth / 2) / Mathf.Cos(theta);
                    float rMin = Mathf.Cos(theta) * r - carWidth;
                    float theta1 = Mathf.Atan(carWheelbase / rMin);
                    rMin = rMin / Mathf.Cos(theta1);
                    float rMax = rMin + carWidth;
                    float lineAngle = carWheelbase / (rMax * 2f * Mathf.PI) * 360f;

                    for (int i = 0; i <= length; i++)
                    {
                        if (i / length >= (maxAngle - lineAngle) / maxAngle)
                        {
                            float x = rMin * Mathf.Cos(maxAngle / length * i * Mathf.Deg2Rad);
                            float z = rMin * Mathf.Sin(maxAngle / length * i * Mathf.Deg2Rad);
                            if (x >= carWheelbase)
                            {
                                if (steeringAngle > 0)
                                {
                                    trackRight.Add(new Vector3(x - carWheelbase, 0, z - rMin + steeringAngle / maxSteerAngle * (carWidth / 2)));
                                }
                                else
                                {
                                    trackRight.Add(new Vector3(x - carWheelbase, 0, -(z - rMin) + carWidth + steeringAngle / maxSteerAngle * (carWidth / 2)));
                                }
                            }

                            x = rMax * Mathf.Cos(maxAngle / length * i * Mathf.Deg2Rad);
                            z = rMax * Mathf.Sin(maxAngle / length * i * Mathf.Deg2Rad);
                            if (x >= carWheelbase)
                            {
                                if (steeringAngle > 0)
                                {
                                    trackLeft.Add(new Vector3(x - carWheelbase, 0, z - rMin + steeringAngle / maxSteerAngle * (carWidth / 2)));
                                }
                                else
                                {
                                    trackLeft.Add(new Vector3(x - carWheelbase, 0, -(z - rMin) + carWidth + steeringAngle / maxSteerAngle * (carWidth / 2)));
                                }
                            }
                        }
                    }
                    trackRight[trackRight.Count - 1] = Vector3.forward * trackRight[trackRight.Count - 1].z;
                    trackLeft[trackLeft.Count - 1] = Vector3.forward * trackLeft[trackLeft.Count - 1].z;
                }
                else
                {
                    float r = (carWheelbase / Mathf.Tan(theta) + carWidth / 2) / Mathf.Cos(theta);
                    float rMin = Mathf.Cos(theta) * r - carWidth;
                    float rMax = rMin + carWidth;
                    float lineAngle = carWheelbase / (rMin * 2f * Mathf.PI) * 360f;
                    for (int i = 0; i <= length; i++)
                    {
                        if (i / length >= (maxAngle - lineAngle) / maxAngle)
                        {
                            float x = -rMin * Mathf.Cos(maxAngle / length * i * Mathf.Deg2Rad);
                            float z = rMin * Mathf.Sin(maxAngle / length * i * Mathf.Deg2Rad);
                            if (steeringAngle > 0)
                            {
                                trackRight.Add(new Vector3(x, 0, z - rMin));
                            }
                            else
                            {
                                trackRight.Add(new Vector3(x, 0, -(z - rMin) + carWidth));
                            }

                            x = -rMax * Mathf.Cos(maxAngle / length * i * Mathf.Deg2Rad);
                            z = rMax * Mathf.Sin(maxAngle / length * i * Mathf.Deg2Rad);
                            if (steeringAngle > 0)
                            {
                                trackLeft.Add(new Vector3(x, 0, z - rMin));
                            }
                            else
                            {
                                trackLeft.Add(new Vector3(x, 0, -(z - rMin) + carWidth));
                            }
                        }
                    }
                    trackRight[trackRight.Count - 1] = Vector3.forward * trackRight[trackRight.Count - 1].z;
                    trackLeft[trackLeft.Count - 1] = Vector3.forward * trackLeft[trackLeft.Count - 1].z;
                }
            }
            track[0] = trackLeft.ToArray();
            track[1] = trackRight.ToArray();
            trackLeft = trackRight = null;
            return track;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Unity实现物体运动时画出轨迹

    本文实例为大家分享了Unity实现物体运动时画出轨迹的具体代码,供大家参考,具体内容如下 1.新建空物体,上赋LineRenderer 2.新建空物体,把轨迹画出来,设计和脚本. 3.LineMark的脚本是 using System.Collections; using System.Collections.Generic; using UnityEngine; public class LineMark : MonoBehaviour { private GameObject clone;

  • Unity实现汽车前后轮倒车轨迹计算

    汽车前后轮倒车轨迹计算附C#源码(Unity),供大家参考,具体内容如下 原理很简单, 都是高中的几何数学部分 需要的参数有: 车前后轴距; 车宽(左前轮与右前轮距离); 当前车轮角度(多数车33.5°); 是否要绘制前轮轨迹线; ///<summary> /// 获取行车轨迹预测index = 0 left轨迹 /// </summary> /// <param name="steeringAngle">方向盘角度</param> //

  • 使用PostGIS完成两点间的河流轨迹及流经长度的计算(推荐)

    目录 基础准备工作 1.PostGIS 的安装 2.加载Post GIS扩展 3.河流矢量图层转成单线格式 4.河流矢量数据导入PostgreSQL数据库 5.河流数据拓扑处理 PG分析处理函数 1.函数编写 2.参数说明 3.内部调用函数说明 4.输出结果验证 基础准备工作 1.PostGIS 的安装 在安装PostGIS前首先必须安装PostgreSQL,然后再安装好的Stack Builder中选择安装PostGIS组件.具体安装步骤可参照PostGIS的安装与初步使用 2.加载Post

  • Python中使用kitti数据集实现自动驾驶(绘制出所有物体的行驶轨迹)

    目录 1.利用IMU.GPS计算汽车移动距离和旋转角度 2.画出kitti车的行驶轨迹 3.画出所有车辆的轨迹 本次内容主要是上周内容的延续,主要画出kitti车的行驶的轨迹 同样的,我们先来看看最终实现的效果: 视频 接下来就进入一步步的编码环节...   1.利用IMU.GPS计算汽车移动距离和旋转角度 计算移动距离 通过GPS计算 #定义计算GPS距离方法 def computer_great_circle_distance(lat1,lon1,lat2,lon2): delta_sigm

  • Go语言中的Array、Slice、Map和Set使用详解

    Array(数组) 内部机制 在 Go 语言中数组是固定长度的数据类型,它包含相同类型的连续的元素,这些元素可以是内建类型,像数字和字符串,也可以是结构类型,元素可以通过唯一的索引值访问,从 0 开始. 数组是很有价值的数据结构,因为它的内存分配是连续的,内存连续意味着可是让它在 CPU 缓存中待更久,所以迭代数组和移动元素都会非常迅速. 数组声明和初始化 通过指定数据类型和元素个数(数组长度)来声明数组. 复制代码 代码如下: // 声明一个长度为5的整数数组 var array [5]int

  • 不错的windows server 2003 工具资源命令集

    这是新年的第一篇日志,呵呵也算是精品吧.在网上闲逛时发现的. accwiz.exe > Accessibility Wizard for walking you through setting up your machine for your mobility needs. 辅助工具向导 acsetups.exe > ACS setup DCOM server executable actmovie.exe > Direct Show setup tool 直接显示安装工具 append

  • DOS下常用的相关网络命令总结

    在DOS下的Microsoft Network Client和Windows 9x的DOS窗口等环境中,有许多很有用的但不包含在DOS自带的命令中的网络命令.那么,有哪些这样的命令呢?下面将它们中常用的命令介绍一下. Arp 显示和修改"地址解析协议"(ARP) 所使用的到以太网的 IP 或令牌环物理地址翻译表.该命令只有在安装了 TCP/IP 协议之后才可用. arp -a [inet_addr] [-N [if_addr]] arp -d inet_addr [if_addr] a

  • DOS下常用网络相关命令解释

    Arp 显示和修改"地址解析协议"(ARP) 所使用的到以太网的 IP 或令牌环物理地址翻译表.该命令只有在安装了 TCP/IP 协议之后才可用. arp -a [inet_addr] [-N [if_addr]] arp -d inet_addr [if_addr] arp -s inet_addr ether_addr [if_addr] 参数 -a 通过询问 TCP/IP 显示当前 ARP 项.如果指定了 inet_addr,则只显示指定计算机的 IP 和物理地址. -g 与 -

  • 一个模仿oso的php论坛程序(之一)第1/2页

    我经常使用oso的论坛,个人感觉挺好的,因此模仿oso的界面编了一个程序,与大家共享.  程序由三部分组成,即显示主题信息,显示论坛信息,增加论坛信息,主题与论坛内容采用主从表关系.  表结构如下:  drop table fr_t_forumtitle;  create table fr_t_forumtitle(     id         integer,     state      varchar(1),     readcount  integer,     replycount 

  • 讲解Python中的递归函数

    在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. 举个例子,我们来计算阶乘n! = 1 x 2 x 3 x ... x n,用函数fact(n)表示,可以看出: fact(n) = n! = 1 x 2 x 3 x ... x (n-1) x n = (n-1)! x n = fact(n-1) x n 所以,fact(n)可以表示为n x fact(n-1),只有n=1时需要特殊处理. 于是,fact(n)用递归的方式写出来就是: def fact(n):

  • C#函数式编程中的缓存技术详解

    缓存技术 该节我们将分成两部分来讲解,第一部分为预计算,第二部分则为缓存.缓存这个技术对应从事开发的人员来说是非常熟悉的,从页面缓存到数据库缓存无处不在,而其最重要的特点就是在第一次查询后将数据缓存,在以后的查询过程中就无需重新计算而直接从内存中将结果返回,大大提高了性能,而我们这里的缓存则集中运用在函数上.  预计算 可能一些人并不能立马理解这个词的含义,所以我们就简单的从生活例子出发介绍一下.很多人在工作中一定会这样做事,比如上级吩咐了你一件事,但是这件事的后半部分要等另一个同事做好之后把对

随机推荐