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 };