用threejs求解三维空间三角形面积

1,143 阅读3分钟

「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战

一、问题描述

在一个三维坐标系中,已知三个点,比如A点坐标:(0, 0, 0),B点坐标:(20, 0, 0), c点坐标:(0, 40, 0),求解这三个点所构成的三角形的面积是多少?

二、解题思路

当拿到这个问题的时候,我第一反应有点懵,不知怎么下手,后来冷静下来仔细想想我发现解题可以分为下面几部:

二维坐标系中的三角形面积求解

在一个二维坐标系中,已知三个点,比如A点坐标:(0, 0),B点坐标:(20, 0), c点坐标:(0, 40),求解这三个点所构成的三角形的面积是多少?

image.png

答:如果我们知道三角形底a,高h,则我可以用公式: S=ah/2,或者我们知道两条边a,b和夹角C,着我们就可以用公式:S=1/2absinC,这是小学数学问题了,但是如果我们知道向量a,和向量b,我们就可以用叉乘,我们就可以用公式:S=1/2|a||b|sin<|a||b|>,因为在坐标系中,所以我们可以用这个公式解题:

向量a = (20, 0);向量b = (0, 40);面积就等于:1/2 * (20, 0) * (0, 40) = 400;

三维坐标系中的三角形面积求解

有了上面的解题思路我们发现,我们可以用向量的叉乘求夹角和面积,当我发现threejs里面有向量后,我决定用threejs 解决这个问题。

答: 向量a = (20, 0, 0);向量b = (0, 40, 0);面积就等于:1/2 * (20, 0, 0) * (0, 40, 0) = 400;

三、编码实现

  1. 先设置三角形的三个点坐标p1,p2,p3
// 三角形的三个点坐标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(0, 40, 0); // 点3坐标
  1. p1,p2两个点确定一个向量v1
// p1,p2两个点确定一个向量
      const v1 = p1.clone().sub(p2);
  1. p1,p3两个点确定一个向量v2
// p1,p3两个点确定一个向量
      const v2 = p1.clone().sub(p3);
  1. 返回三角形顶点p1对应夹角余弦值
const CosineValue = v1.dot(v2) / (v1.length() * v2.length());
  1. 返回三角形顶点p1对应夹角角度
Math.acos(CosineValue) * 180) / Math.PI
  1. 三角形面积计算
areaOfTriangle(
    p1: THREE.Vector3,
    p2: THREE.Vector3,
    p3: THREE.Vector3
  ): number {
    let v1 = new THREE.Vector3();
    let v2 = new THREE.Vector3();
    // 通过两个顶点坐标计算其中两条边构成的向量
    v1 = p1.clone().sub(p2);
    v2 = p1.clone().sub(p3);

    const v3 = new THREE.Vector3();
    // 三角形面积计算
    v3.crossVectors(v1, v2);
    const s = v3.length() / 2;
    return s;
  }

6.看结果

我们得出:三角形两条边夹角余弦值为 0, 三角形两条边夹角为90三角形的面积为400

image.png

四、思考

任意三角形的面积

有了上面三角形的公式,我们可以得出任意三角形的面积和夹角了,比如

      const p1 = new THREE.Vector3(0, 0, 20); // 点1坐标
      const p2 = new THREE.Vector3(20, 0, 0); // 点2坐标
      const p3 = new THREE.Vector3(0, 40, 0); // 点3坐标

p1,p2,p3构成的三角形的面积是多少?

image.png

答: 三角形两条边夹角余弦值 0.3162277660168379三角形两条边夹角 71.56505117707799三角形的面积为600

任意长方形的面积

如果知道长方体p1,p2,p3,p4坐标求面积?

      const p1 = new THREE.Vector3(0, 0, 20); // 点1坐标
      const p2 = new THREE.Vector3(20, 0, 0); // 点2坐标
      const p3 = new THREE.Vector3(0, 40, 0); // 点3坐标
      const p4 = new THREE.Vector3(20, 40, 0); // 点4坐标

答:长方体就是两个三角形,所以我们的公式如下:

// 长方形
  areaOfCuboid(
    p1: THREE.Vector3,
    p2: THREE.Vector3,
    p3: THREE.Vector3,
    p4: THREE.Vector3
  ): number {
    let v1 = new THREE.Vector3();
    let v2 = new THREE.Vector3();
    let v3 = new THREE.Vector3();
    let v4 = new THREE.Vector3();
    // 通过两个顶点坐标计算其中两条边构成的向量
    v1 = p1.clone().sub(p2);
    v2 = p1.clone().sub(p3);
    v3 = p4.clone().sub(p2);
    v4 = p4.clone().sub(p3);

    const v5 = new THREE.Vector3();
    const v6 = new THREE.Vector3();
    // 三角形面积计算
    v5.crossVectors(v1, v2);
    v6.crossVectors(v3, v4);
    console.log(v5, v6);
    const s1 = v5.length() / 2;
    const s2 = v6.length() / 2;
    return s1 + s2;
  }

结果: 长方体的面积为1000

关联

vue3.0 + ts + threejs 实现简单的demo