1.已知方向向量direction和起始点位originPosition,求将起始点位沿方向向量移动距离d后的结束点位。
方式一
const endPosition = originPosition.clone().add(direction.clone().multiplyScalar(d));
// 同理减去一段距离
const endPosition = originPosition.clone().sub(direction.clone().multiplyScalar(d));
方式二
const endPosition = originPosition.clone().addScaledVector(direction.clone(), d);
2.已知点位A、B判断点C在向量AB左侧还是右侧
使用向量的叉乘(叉积),向量的叉乘的结果为一个垂直于该平面的向量,方向可以根据右手螺旋定则来判断。
const AC = c.clone().sub(A).normalize(); // AC向量的单位向量
const crossVector = B.cloen().sub(A).normalize().cross(AC); // AB向量与AC向量的单位向量的叉积
// 根据右手螺旋定则 确定朝向即可对应y的正负
if(crossVector.y>0){
// 右侧
}else if(crossVector.y<0){
// 左侧
}
3.获取两个点的中间点位
const midpoint = new THREE.Vector3();
midpoint.addVectors(startPoint, endPoint).multiplyScalar(0.5);
4.两点之间均匀取点
const point = new THREE.Vector3().lerpVectors(outsideMeeting, curPoint, t);
5.获取向量的交点
// 获取两个向量的交点
getIntersection(vector1Start, vector1End, vector2Start, vector2End) {
// 创建射线
const ray = new THREE.Ray(vector1Start, vector1End.clone().sub(vector1Start).normalize());
// 创建平面
const plane = new THREE.Plane().setFromCoplanarPoints(
vector2Start,
vector2End,
vector2Start.clone().cross(vector2End)
);
const d1 = vector1End.clone().sub(vector1Start).normalize();
const d2 = vector2End.clone().sub(vector2Start).normalize();
const dotValue = d1.clone().dot(d2);
// 获取交点
const intersection = new THREE.Vector3();
const intersectPoint = ray.intersectPlane(plane, intersection);
if (dotValue === -1 || !intersectPoint) {
return vector1End;
}
return intersectPoint;
}
6.平面内旋转获取结束点位
// 平面内旋转向量后的结束点位
/**
*
* @param {*} startPoint 起始点位
* @param {*} centerPoint 圆心
* @param {*} radius 半径
* @param {*} radians 旋转的弧度
*/
getRotatedEndPoint(startPoint, centerPoint, radius, radians) {
const CP = startPoint.clone().sub(centerPoint).normalize();
const rotationMatrix = new THREE.Matrix4().makeRotationAxis(
new THREE.Vector3(0, 1, 0),
radians
);
const rotatedCP = CP.applyMatrix4(rotationMatrix);
const nextPosition = centerPoint
.clone()
.add(rotatedCP.clone().normalize().multiplyScalar(radius));
return nextPosition;
}
7.将方向向量应用四元数之后得到新的方向向量
let baseOutDirection = new THREE.Vector3();// 原始方向
// 将旋转角转化为四元数
const quaternion = new THREE.Quaternion();
quaternion.setFromEuler(insModel.rotation);
// 将方向向量转化为四元数 由方向 new THREE.Vector3(1, 0, 0) 到 baseOutDirection 组成的四元数
const directionQuaternion = new THREE.Quaternion();
directionQuaternion.setFromUnitVectors(new THREE.Vector3(1, 0, 0), baseOutDirection);
const newDirectionQuaternion = quaternion.clone().multiply(directionQuaternion);
const newDirection = new THREE.Vector3(1, 0, 0);
baseOutDirection = newDirection.applyQuaternion(newDirectionQuaternion);