模型按照固定路线转向移动

本文描述了一种使用THREE.js库的方法,通过生成样条曲线并结合切线计算,创建了一个可复用的CarMove函数,以控制汽车模型沿给定路径平滑移动,同时实现转向。作者寻求改进意见以优化代码和性能。
摘要由CSDN通过智能技术生成

需求里面有个功能是汽车按着路线行驶,用动画做过一遍了,但是复用不太好用,而且代码冗余,动作僵硬,如果需要实现丝滑转弯的话需要写更多的代码,

所以我想着写个函数能够实现把参数穿进去根据点的集合移动车子,

原理,生成一条样条曲线,渲染的时候不断用样条曲线上的点更新车的位置来实现移动车子;

转向的话我这里是用切线,用两个相近的点生成一条切线,转成单位向量,用四元数处理两个单位向量(模型朝向的单位向量和切线的单位向量),最后赋值给模型的四元数就完成了

import * as THREE from "three";
export function carMove(pointNumber: number, mesh: any, points: THREE.Vector3[], camera: THREE.Camera, renderer: THREE.WebGLRenderer, scene: THREE.Scene) {
    //第一个参数曲线上的点,点越多,移动的越慢,mesh是小车的模型,points是车辆的参考路径,后面的就是老三样
    const curve = new THREE.CatmullRomCurve3(points);
    //更新下模型的方向矩阵吧,我是这么理解的
    mesh.updateMatrix();
    const localMatrix = mesh.matrix.clone();
    const forwardVector = new THREE.Vector3();

    // 获取模型的前方向
    forwardVector.setFromMatrixColumn(localMatrix, 2);

    // 单位化前方向
    forwardVector.normalize();
   //从第一个点出发
    let pathIndex = 1; 
    function initAnimate() {
        if (pathIndex === pointNumber-1) {    
            //如果你要循环执行的话把return换成重新赋值,pathIndex=0
            return
        }
        pathIndex += 1;
        //判断模型是否加载成功了
        if (mesh) {
            //这里其实就是获取两个相近的点,形成一个向量,近似于切线的单位向量
            // 样条曲线上某个点的比值(0-1)之间
            const sphereCurveIndex = pathIndex / pointNumber; 
            // 样条曲线上某个点的比值(0-1)之间
            const sphereCurveIndex1 = (pathIndex - 1) / pointNumber; 

            const positionVec = curve.getPointAt(sphereCurveIndex); //获取曲线上位置的点,传值为0-1的小数表示整个线段的位置
            const positionVec1 = curve.getPointAt(sphereCurveIndex1);
            let tangent = new THREE.Vector3(positionVec.x - positionVec1.x, positionVec.y - positionVec1.y, positionVec.z - positionVec1.z)
            tangent.normalize()
            //这一行是一点点移动车的位置
            mesh.position.set(positionVec.x, positionVec.y, positionVec.z);
            // 这三行是让小车朝向切线方向,用到了四元数,setFromUnitVectors
            const q = new THREE.Quaternion();
            q.setFromUnitVectors(forwardVector, tangent);
            // 把四元数赋值给模型的方向矩阵
            mesh.quaternion.copy(q);


        }
        requestAnimationFrame(initAnimate);
        renderer.render(scene, camera);
    }
    initAnimate()
}

这是我用的点的集合

let points = [
  new THREE.Vector3(0, 0, 0),
  new THREE.Vector3(-0.2, 0, .45),
  new THREE.Vector3(8, 0, 0.5),
  new THREE.Vector3(20, 0, 0.5),
  new THREE.Vector3(20, 0, -20),
  new THREE.Vector3(5, 0, -20),
  new THREE.Vector3(-2.3, 0, -20),
  new THREE.Vector3(-2.3, 0, -5),
  new THREE.Vector3(0, 0, -5),
  new THREE.Vector3(0, 0, 0.2),


 
];
 carMove(600, FireTruck, points, camera, renderer, scene);

大概就是这些,大家有什么可以改进的地方可以的话,给我也说下,拜托了,

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
好的,我可以使用Python编程语言来帮你绘制一辆简易的可以移动的智能小车。首先,我们需要安装Python的图形库matplotlib来绘制车辆模型。 ```python import matplotlib.pyplot as plt class SmartCar: def __init__(self, length, width): self.length = length self.width = width self.x = 0 # 初始位置x坐标 self.y = 0 # 初始位置y坐标 self.angle = 0 # 初始角度 def draw_car(self): # 绘制矩形车身 rectangle = plt.Rectangle((self.x, self.y), self.length, self.width, fc='red') plt.gca().add_patch(rectangle) # 绘制质心坐标 centroid_x = self.x + self.length / 2 centroid_y = self.y + self.width / 2 plt.plot(centroid_x, centroid_y, 'bo', markersize=5) # 设置绘图参数 plt.axis('equal') plt.xlim(-self.length, self.length) plt.ylim(-self.width, self.width) plt.gca().set_aspect('equal', adjustable='box') # 显示绘制结果 plt.show() def move_forward(self, distance): # 前进移动 self.x += distance * math.cos(math.radians(self.angle)) self.y += distance * math.sin(math.radians(self.angle)) def move_backward(self, distance): # 后退移动 self.x -= distance * math.cos(math.radians(self.angle)) self.y -= distance * math.sin(math.radians(self.angle)) def turn(self, angle): # 转向 self.angle += angle ``` 以上代码定义了一个SmartCar类,包含了绘制车辆、前进、后退和转向等功能。你可以根据需要自行调整车辆的尺寸、初始位置和转向角度。调用`draw_car`方法可以绘制车辆模型,并在图中显示质心坐标。使用`move_forward`和`move_backward`方法可以手动控制车辆前进和后退,使用`turn`方法可以手动控制车辆转向。 请注意,在运行以上代码之前,你需要先安装matplotlib库。你可以使用以下命令来安装: ``` pip install matplotlib ``` 希望以上代码能够满足你的需求,如果有任何问题,请随时提问。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值