首页 新闻 会员 周边 捐助

用js如何判断某点是否在一条线段上?

0
悬赏园豆:5 [已解决问题] 解决于 2019-04-27 20:28

在二维空间,已知一条线段两个端点的坐标,还有任意一点的坐标。如何封装一个函数,判断该点是否在这条线段上?这是前几天面试遇到的难题,求高手解答。

zanetti的主页 zanetti | 初学一级 | 园豆:128
提问于:2019-03-15 23:31
< >
分享
最佳答案
0

这是一个数学问题,假如有点 A (x1,y1) 、B (x2,y2)、C (x3,y3)
计算他们的斜率 k = (y1-y2)/(x1-x2); 但是, x1如果和 x2 相等,则 k为无穷大,所以,我们代码里面,一般用数组
k = [ y1-y2 , x1-x2 ]
令 a = y1 - y2; b = x1 - x2; 然后取绝对值,在除以他们的最大公倍数,就能够将 k 化简-> 最后,k 如果相等,就是共线,事实上这也是我们常提的一个概念,叫向量,下面给出模拟代码

    function gcd(a,b){
        //计算最大公倍数
        if(b == 0){
            return a;
        }
        var r = a % b;
        return gcd(b,r);
    }
    
    
    var p1 ={x:1,y:2};
    var p2 = {x:2,y:10};
    
    var a = p1.y - p2.y;
     var b = p1.x - p2.x;
    var g = gcd(Math.abs(a),Math.abs(b));//计算最大公倍数
    a = a / g;
    b = b / g;
    var  k = [a,b]; //向量 k
    
    //最后,可以通过计算多个点的斜率(向量) k ,判断是否共线
收获园豆:5
muamaker | 小虾三级 |园豆:763 | 2019-04-20 16:52

回答得相当详细,终于明白了,感谢!

zanetti | 园豆:128 (初学一级) | 2019-04-27 20:27
其他回答(2)
0

横坐标相等,纵坐标在区间内

地火水 | 园豆:1290 (小虾三级) | 2019-03-16 10:04
0

这是一个数学问题,根据两个点可以求出这个直线的一个表达式,例y=kx+b这样的,然后将这个点带进去看等式成不成立(if判断),不成立就不在这条直线上,如果是线段,那就在等式比较之前判断横坐标和纵坐标是否在两个端点坐标之内就行了,两个都成立,就在线段上,具体代码你可以尝试写一下

刘下来 | 园豆:919 (小虾三级) | 2019-03-16 10:08
function dotOnLine(coords = {}){
                let defaults = {
                    dot: [],
                    terminal1: [],
                    terminal2: []
                };

                Object.assign(defaults, coords);

                let {dot, terminal1, terminal2} = defaults;
                let isBetweenX = false;
                let isBetweenY = false;

                if(terminal1[0] < terminal2[0]){
                    //x1 < x2
                    if(dot[0] >= terminal1[0] && dot[0] <= terminal2[0]){
                        //dotX 在两端点横坐标之间
                        isBetweenX = true;
                    }else{
                        //dotX 不在两端点横坐标之间
                        isBetweenX = false;
                    }
                }else{
                    //x1 >= x2
                    if(dot[0] >= terminal2[0] && dot[0] <= terminal1[0]){
                        //dotX 在两端点横坐标之间
                        isBetweenX = true;
                    }else{
                        //dotX 不在两端点横坐标之间
                        isBetweenX = false;
                    }
                }

                if(terminal1[1] < terminal2[1]){
                    //y1 < y2
                    if(dot[1] >= terminal1[1] && dot[1] <= terminal2[1]){
                        //dotY 在两端点横坐标之间
                        isBetweenY = true;
                    }else{
                        //dotY 不在两端点横坐标之间
                        isBetweenY = false;
                    }
                }else{
                    //y1 >= y2
                    if(dot[1] >= terminal2[1] && dot[1] <= terminal1[1]){
                        //dotY 在两端点横坐标之间
                        isBetweenY = true;
                    }else{
                        //dotY 不在两端点横坐标之间
                        isBetweenY = false;
                    }
                }

                if(isBetweenX && isBetweenY){
                    //dot 有可能在线段上
                    let k = (terminal2[1] - terminal1[1]) / (terminal2[0] - terminal1[0]);
                    let b = terminal1[1] - terminal1[0] * k;

                    if(dot[1] === k * dot[0] + b){
                        //dot 在线段上
                        return true;
                    }else{
                        //dot 不在线段上
                        return false;
                    }
                }else{
                    //dot 没可能在线段上
                    return false;
                }
            };

let obj3 = {
                dot: [10, 0],
                terminal1: [10, 20],
                terminal2: [10, -5]
            };

console.log(dotOnLine(obj3));

我按照你说的思路写了这样的函数,用其它点测试时没问题,但是用 obj3 (平行于 y 轴的线段)进行测试,却打印出 false。请问这种情况该怎么办呢?谢谢

支持(0) 反对(0) zanetti | 园豆:128 (初学一级) | 2019-03-16 18:53
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册