直线和平面的交点、交点是否在区域内部、两个向量的叉积和、根点到平面的距离据3个点,计算空间平面的方程、已知三点坐标,求平面的法向量、求线面交点 线面平行返回undefined、 求交点是否在线段上





/**
     * 求交点 线面相交 求交点
     * @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;
    }









©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,639评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,093评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,079评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,329评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,343评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,047评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,645评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,565评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,095评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,201评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,338评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,014评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,701评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,194评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,320评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,685评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,345评论 2 358

推荐阅读更多精彩内容