直线和平面的交点、交点是否在区域内部、两个向量的叉积和、根点到平

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









上一篇下一篇

猜你喜欢

热点阅读