threejs实现相对直线镜像

834 阅读2分钟

threejs实现相对直线镜像

思路

使用rayCurrentSelector选取需要进行镜像的线

使用vector3进行进行计算,主要思路是先需要获取进行镜像的标线line1,和线line2的每个点的坐标。

然后用line2的每个点和标线line1的其中一个点计算向量**.clone().sub**

再用这个向量进行投影**.clone().projectOnVector(v1)**

获得了line1每个点和向量line2的垂直距离new2

将这个向量pOV取反并平移到pov末端所在的位置,就是镜像后线段的端点的位置

备注:需要考虑平移new2到pov顶点的位置,相加即可

import { CLine, CPoint } from "../../../../js/graphic/index";
import { points3D_for_points2D } from "../../../../js/util/funUtil.js";
import {
  showMessage,
  showMessageClose,
} from "../../../../js/tools/showMessage";
import { Scene } from "../../../../libs/three.module";
//

let collection = {
  mirror1: null,
  mirror2: null,
};

const addCPoints = function(pointArray, group) {
  pointArray.forEach((item) => {
    let cpoint = new CPoint(
      item,
      window.view.currentWorkPlane.normal,
      "/png/dot_dot.png"
    );
    cpoint.vertexs = item;
    group.add(cpoint);
  });
};
//进行计算并绘制图像
const clickEvent = function(rayCurrentSelector) {
  let tools = window.view.tools;
  console.log("rayCurrentSelector", rayCurrentSelector);
  if (rayCurrentSelector === undefined) {
    return;
  }

  if (rayCurrentSelector == null) {
    showMessage("请选择直线");
    return;
  }
  let object = rayCurrentSelector.object;
  // 步驟記錄
  if (tools.step == 0) {
    tools.step = 1;
    let mirror_line2 = tools.getItem("mirror_line2");
    tools.updateLine("mirror_line2", object.vertexs);
    collection.mirror1 = object;
  } else if (tools.step == 1) {
    // new!!!
    let coordinates1 = collection.mirror1.vertexs;
    let coordinates2 = object.vertexs;
    let v1 = coordinates1[1].clone().sub(coordinates1[0]);
    //选择的第二条线的第一个点-镜像线的投影
    let v2 = coordinates2[0].clone().sub(coordinates1[0]);
    let ov2 = coordinates1[0].clone();
    let pOV2 = v2.clone().projectOnVector(v1);
    let move2 = ov2.clone().add(pOV2);
    let new2 = v2
      .clone()
      .sub(pOV2)
      .negate()
      .add(move2);
    // tools.addPoint(new2, false, 0xf45b6d);
    let v3 = coordinates2[1].clone().sub(coordinates1[0]);
    let ov3 = coordinates1[0].clone();
    let pOV3 = v3.clone().projectOnVector(v1);
    let move3 = ov3.clone().add(pOV3);
    let new3 = v3
      .clone()
      .sub(pOV3)
      .negate()
      .add(move3);
    // tools.addPoint(new3, false, 0xf45b6d);
    tools.updateLine("mirror_line2", [0, 0, 0]);
    let newLine = new CLine();
    newLine.draw([new2, new3]);
    window.view.currentWorkPlane.children[0].add(newLine);
    addCPoints([new2, new3], object);
    tools.step = 0;
    showMessageClose();
  }
};

const moveEvent = function(rayCurrentSelector) {
  if (rayCurrentSelector.length == 0) {
    window.view.tools.updateLine("mirror_line", [0, 0, 0]);
    return;
  }

  let object = rayCurrentSelector[0].object;
  if (object.type == "Line2" && object.name == "cline") {
    window.view.tools.updateLine("mirror_line", object.vertexs);
    return rayCurrentSelector[0];
  } else {
    window.view.tools.updateLine("mirror_line", [0, 0, 0]);
    return null;
  }
};

const debounce = function(fn, delay) {
  let timer = null;
  return function() {
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(fn, delay);
  };
};

const initTools = function() {
  let tools = window.view.tools;
  tools.clear();
  tools.step = 0;
  tools.addLine("mirror_line", false, 0xffb4b6);
  tools.addLine("mirror_line2", false, 0xf45b6d);
  let mirror_line = tools.getItem("mirror_line");
  mirror_line.renderOrder = 40;
  mirror_line.material.depthWrite = false;

  let mirror_line2 = tools.getItem("mirror_line2");
  mirror_line2.renderOrder = 40;
  mirror_line2.material.depthWrite = false;
  //
  collection = {
    mirror1: null,
    mirror2: null,
  };
};

// 程序入口
const _main = function(type) {
  initTools();
  showMessage("请选择要镜像的两条直线");
  window.view.cevent.registerEvent("draftMirror", {
    click: clickEvent,
    mousemove: moveEvent,
  });
};

const draftMirror = function() {
  _main();
};

export { draftMirror };