直线和平面的交点、交点是否在区域内部、两个向量的叉积和、根点到平
2020-02-24 本文已影响0人
宿州刘德华
/**
* 求交点 线面相交 求交点
* @param line
* @param polygon
* @returns {boolean|Array}
*/
function getPointInPolygon(line, polygon) {
let normal = getNormal(polygon[0], polygon[1], polygon[2]);
let lineNormal = [];
let lineX = line[0].x - line[1].x;
let lineY = line[0].y - line[1].y;
let lineZ = line[0].z - line[1].z;
lineNormal.push({"x": lineX, "y": lineY, "z": lineZ});
let result = CalPlaneLineIntersectPoint(normal, polygon[1], lineNormal, line[0]);
if (result) {
return result;
}
return false;
}
/**
* 求交点是否在区域内部
* @param point
* @param polygon
* @returns {boolean}
* @constructor
*/
function JudgePointInPolygon(point, polygon) {
let p1 = polygon[0];
let p2 = polygon[1];
let p3 = polygon[2];
let p4 = polygon[3];
let n1, n2, n3, n4, n5, n6, n7, n8;
n1 = {"x": p2.x - p1.x, "y": p2.y - p1.y, "z": p2.z - p1.z};
n2 = {"x": point.x - p1.x, "y": point.y - p1.y, "z": point.z - p1.z};
n3 = {"x": p4.x - p3.x, "y": p4.y - p3.y, "z": p4.z - p3.z};
n4 = {"x": point.x - p3.x, "y": point.y - p3.y, "z": point.z - p3.z};
n5 = {"x": p3.x - p2.x, "y": p3.y - p2.y, "z": p3.z - p2.z};
n6 = {"x": point.x - p2.x, "y": point.y - p2.y, "z": point.z - p2.z};
n7 = {"x": p4.x - p1.x, "y": p4.y - p1.y, "z": p4.z - p1.z};
n8 = {"x": point.x - p4.x, "y": point.y - p4.y, "z": point.z - p4.z};
return !(VectorMultiplication(n1, n2) * VectorMultiplication(n3, n3) >= 0 && VectorMultiplication(n5, n6) * VectorMultiplication(n7, n8) >= 0);
}
/**
* 两个向量的叉积和
* @param n
* @param m
* @returns {number}
* @constructor
*/
function VectorMultiplication(n, m) {
return n.y * m.z - m.y * n.z + n.z * m.x - n.x * m.z + n.x * m.y - n.y * m.x;
}
/**
* 求交点是否在线段上
* @param point
* @param polyline
* @returns {boolean}
* @constructor
*/
function JudgePointInPolyline(point, polyline) {
let lineLength = Math.sqrt(Math.pow((polyline[0].x - polyline[1].x), 2) + Math.pow((polyline[0].y - polyline[1].y), 2) + Math.pow((polyline[0].z - polyline[1].z), 2));
let one = Math.sqrt(Math.pow((point.x - polyline[1].x), 2) + Math.pow((point.y - polyline[1].y), 2) + Math.pow((point.z - polyline[1].z), 2));
let two = Math.sqrt(Math.pow((point.x - polyline[0].x), 2) + Math.pow((point.y - polyline[0].y), 2) + Math.pow((point.z - polyline[0].z), 2));
let di = one + two - lineLength;
if (di * 100 < 1) {
return true;
}
return false;
}
/**
* 求线面交点 线面平行返回undefined
* @param planeVector 平面的法线向量,长度为3
* @param planePoint 平面经过的一点坐标,长度为3
* @param lineVector 直线的方向向量,长度为3
* @param linePoint 直线经过的一点坐标,长度为3
* @returns {Array} 返回交点坐标,长度为3
* @constructor
*/
function CalPlaneLineIntersectPoint(planeVector, planePoint, lineVector, linePoint) {
let returnResult = [];
let vp1, vp2, vp3, n1, n2, n3, v1, v2, v3, m1, m2, m3, t, vpt;
vp1 = planeVector[0].x;
vp2 = planeVector[0].y;
vp3 = planeVector[0].z;
n1 = planePoint.x;
n2 = planePoint.y;
n3 = planePoint.z;
v1 = lineVector[0].x;
v2 = lineVector[0].y;
v3 = lineVector[0].z;
m1 = linePoint.x;
m2 = linePoint.y;
m3 = linePoint.z;
vpt = v1 * vp1 + v2 * vp2 + v3 * vp3;
//首先判断直线是否与平面平行
if (vpt == 0) {
returnResult = undefined;
} else {
t = ((n1 - m1) * vp1 + (n2 - m2) * vp2 + (n3 - m3) * vp3) / vpt;
returnResult.x = m1 + v1 * t;
returnResult.y = m2 + v2 * t;
returnResult.z = m3 + v3 * t;
}
return returnResult;
}
/**
* 已知三点坐标,求平面的法向量
* @param p1
* @param p2
* @param p3
* @returns {[]}
*/
function getNormal(p1, p2, p3) {
let point = [];
let x = ((p2.y - p1.y) * (p3.z - p1.z) - (p2.z - p1.z) * (p3.y - p1.y));
let y = ((p2.z - p1.z) * (p3.x - p1.x) - (p2.x - p1.x) * (p3.z - p1.z));
let z = ((p2.x - p1.x) * (p3.y - p1.y) - (p2.y - p1.y) * (p3.x - p1.x));
point.push({"x": x, "y": y, "z": z});
return point;
}
/**
* 根据3个点,计算空间平面的方程
* Ax+By+Cz+D=0
* 输入参数:point3fArray---空间中3个点的坐标,大小为3;输入点>3时,只取前3个点
* 输出参数A,B,C,D
* 返回值:true---计算成功;false----计算失败
* @param point3fArray
* @returns {boolean}
* @constructor
*/
function GetPanelEquation(point3fArray) {
if (point3fArray.length < 3) {
return undefined;
}
let A, B, C, D;
A = point3fArray[0].y * (point3fArray[1].z - point3fArray[2].z) +
point3fArray[1].y * (point3fArray[2].z - point3fArray[0].z) +
point3fArray[2].y * (point3fArray[0].z - point3fArray[1].z);
B = point3fArray[0].z * (point3fArray[1].x - point3fArray[2].x) +
point3fArray[1].z * (point3fArray[2].x - point3fArray[0].x) +
point3fArray[2].z * (point3fArray[0].x - point3fArray[1].x);
C = point3fArray[0].x * (point3fArray[1].y - point3fArray[2].y) +
point3fArray[1].x * (point3fArray[2].y - point3fArray[0].y) +
point3fArray[2].x * (point3fArray[0].y - point3fArray[1].y);
D = -point3fArray[0].x * (point3fArray[1].y * point3fArray[2].z - point3fArray[2].y * point3fArray[1].z) -
point3fArray[1].x * (point3fArray[2].y * point3fArray[0].z - point3fArray[0].y * point3fArray[2].z) -
point3fArray[2].x * (point3fArray[0].y * point3fArray[1].z - point3fArray[1].y * point3fArray[0].z);
return {A: A, B: B, C: C, D: D};
}
/**
* 点到平面的距离
* @param point
* @param polygon
* @returns {number|undefined}
*/
function point2polygonDistance(point, polygon) {
let panel = GetPanelEquation(polygon);
if (panel) {
let distance = Infinity;
let temp = Math.sqrt(panel.A * panel.A + panel.B * panel.B + panel.C * panel.C);
if (temp <= 0.001) {
return undefined;
}
distance = 1.0 * Math.abs(panel.A * point.x + panel.B * point.y + panel.C * point.z + panel.D) / temp;
return distance;
}
return undefined;
}