目录
两向量归一化后点乘 就是等于两向量夹角的余弦值,即 1 * 1 * cosθ
点乘满足交换律,但向量的方向会对夹角计算有影响,如下计算三角形夹角θ
点乘的含义
- 向量a长度 * 向量b长度 * cos(ab夹角)
- 向量a在向量b上的投影 * 向量b
- 点乘 = |a||b|cosθ
两向量归一化后点乘 就是等于两向量夹角的余弦值,即 1 * 1 * cosθ
// 两向量垂直
const a = new THREE.Vector3(0, 10, 0);
const b = new THREE.Vector3(20, 0, 0);
const dot = a.dot(b);//向量a与向量b点乘,返回结果是一个数字
console.log('点乘结果',dot); // 0 a b正交
// a、b向量归一化后点乘 就是等于两向量夹角的余弦值
const cos = a.normalize().dot(b.normalize());
console.log('向量夹角余弦值',cos); // 0
const rad = Math.acos(cos);//反余弦计算向量夹角弧度 余弦转弧度
console.log('向量夹角弧度',rad); // 1.570
// 弧度转角度
const angle = THREE.MathUtils.radToDeg(rad);
console.log('向量夹角角度值',angle); // 90
点乘满足交换律,但向量的方向会对夹角计算有影响,如下计算三角形夹角θ
得到夹角是 45度
// 三角形的三个点坐标p1,p2,p3
const p1 = new THREE.Vector3(0,0,0);// 点1坐标
const p2 = new THREE.Vector3(20,0,0);// 点2坐标
const p3 = new THREE.Vector3(10,10,0);// 点3坐标
const a = p3.clone().sub(p1);// p1,p3两个点确定一个向量 p3-p1
const b = p2.clone().sub(p1);// p1,p2两个点确定一个向量 p2-p1
// a、b向量归一化后点乘 就是 两向量夹角的cos 点乘 = |a||b|cosθ
const cos = a.normalize().dot(b.normalize());
const rad = Math.acos(cos);//反余弦计算向量夹角弧度
const angle = THREE.MathUtils.radToDeg(rad);// 弧度转角度
console.log('向量夹角角度值',angle); // 45
当a向量方向由 p1->p3 变为 p3->p1时,将向量方向反过来,得到的是 135度
const a = p1.clone().sub(p3);//和p3.clone().sub(p1)向量方向反过来 重新计算角度值 p1-p3
const b = p2.clone().sub(p1);// p1,p2两个点确定一个向量 p2-p1
// a、b向量归一化后点乘 就是 两向量夹角的cos 点乘 = |a||b|cosθ
const cos = a.normalize().dot(b.normalize());
const rad = Math.acos(cos);//反余弦计算向量夹角弧度
const angle = THREE.MathUtils.radToDeg(rad);// 弧度转角度
console.log('向量夹角角度值',angle); // 135
当b向量方向由 p2->p1 变为 p1->p2时,将b向量方向反过来,夹角又会变为 45度
const a = p1.clone().sub(p3);//和p3.clone().sub(p1)向量方向反过来 重新计算角度值
const b = p1.clone().sub(p2);// p1,p2两个点确定一个向量 p2-p1
// a、b向量归一化后点乘 就是 两向量夹角的cos 点乘 = |a||b|cosθ
const cos = a.normalize().dot(b.normalize());
const rad = Math.acos(cos);//反余弦计算向量夹角弧度
const angle = THREE.MathUtils.radToDeg(rad);// 弧度转角度
console.log('向量夹角角度值',angle); // 45
点乘的几何的意义
正交
两向量正交 <=> 两向量夹角为 90度 <=> cosθ为0 <=> 点积为0
平行
两向量平行 <=> 两向量夹角为0度 <=> cosθ为1 <=> 点积为1 (两向量长度是1)
逆向
两向量相反 <=> 两向量夹角为180度 <=> cosθ为-1 <=> 点积为-1 (两向量长度是1)
Threejs源码 实现点乘 dot
点乘判断物体在人前或人后
物体绕着人360挪动位置,创建的不同位置人指向物体的向量b,会发现向量b与向量a的夹角处于0~180度之间。
余弦规律
角度θ在0 ~180度范围内,随着θ度数的增加,角度θ余弦值cos(θ)下降。换句话说,向量b与向量a夹角越小,对应的余弦值越大。余弦值满足负相关
分析:向量a和b夹角,在0~180度的范围内的前提下
当a和b点乘a. dot(b)大于0,意味着cos(θ)大于0,cos(θ)大于0意味着夹角θ是0~90度,θ是0~90度说明物体在人的前方。
a和b点乘 a.dot (b)小于0,意味着cos(θ)小于0,0~180度的范围内,cos(θ)小于0,意味着夹角θ是90~180度,θ是90~180度说明物体在人的后方。
// 已知条件
person.position.set(0, 0, 2);//人位置
mesh.position.set(2, 0, -3);//物体位置
// a向量:人的正前方沿着z轴负半轴
const a = new THREE.Vector3(0, 0, -1);
// 物体坐标减去人坐标,创建一个人指向物体的向量
const b = mesh.position.clone().sub(person.position);
const dot = a.dot(b);//向量a和b点乘
if (dot > 0) {// 物体在人前面,向量a和b夹角0~90度,夹角余弦值大于0,a和b点乘`.dot()`大于0。
console.log('物体在人前面'); // 物体在人前面
} else if (dot < 0) {// 物体在人后面,向量a和b夹角0~180度,夹角余弦值小于0,a和b点乘`.dot()`小于0
console.log('物体在人后面');
}