js怎么判断这个点在a还是b

option = {
  xAxis: { type: 'log' },
  yAxis: {
    type: 'value',
    min: 0,
    max: function (value) {
      return value.max;
    },
    axisLabel: {
      formatter: '{value} %'
    }
  },
  series: [
    {
      //  name: '紫色',
      type: 'line',
      data: [
        [0.0004, 500],
        [0.001, 200],
        [0.003, 140],
        [0.02, 120],
        [0.5, 120],
        [0.5, 110],
        [10, 110],
        [100, 110]
      ],
      itemStyle: {
        normal: {
          color: '#ad46f3'
        }
      }
    },
    {
      symbolSize: 20,
      data: [[3.03, 4.23]],
      type: 'scatter',
      itemStyle: {
        normal: {
          color: '#33f333'
        }
      }
    }
  ]
};

https://echarts.apache.org/ex...

image.png

阅读 2.7k
2 个回答

如果是单纯的判断在任意曲线哪一侧的话,需要一些图形学的知识,因为曲线还有闭合、交叉的情况,不过既然是折线图,那就好办,因为折线图不会闭合、且x值是唯一的。
假设折线的方程是 f(x),点坐标是 [x, y],那么 f(x) > y 就是在 B 区,把比较符号反过来就是在 A 区,相等则是在折线上。
折线函数大致长这样——

function f(x, data){
    // 按横轴值排序
    const sorted = data.sort(([a], [b]) => a - b);

    // 找到 x 落点区间,用 for 循环效率会高一点
    const [
        [minX, minY],
        [maxX, maxY]
    ] = sorted.reduce(
            (prev, [nextX, nextY]) => {
                let [[minX], [maxX]] = prev;
                if(nextX > maxX) return prev;
                if(nextX <= x){
                    prev[0][0] = nextX;
                    prev[0][1] = nextY;
                } else {
                    prev[1][0] = nextX;
                    prev[1][1] = nextY;
                }
                return prev
            }
        ),
        [[data[0]], data[data.length - 1]]
    );
    // 两点式直线方程变体
    return (x - minX) * (maxY- minY) / (maxX - minX) + minY;
}

_

不确定能不能直接运行。

楼上已经指出这种折线图不会闭合、且x值是唯一单向的。
因为折线并没有简单的函数,而是由点集数据给出,所以这个问题其实转换为在P(x,y) 与点集子区间关系上其中x0<=x<=x1
再根据要求,转换为比较
直线X=x与直线段((x0,y0),(x1,y1)交点(x,yj)y的关系上,如果y<yj,则P属于B区,如果y=yj,则P属于折线(是折线上的点),如果y>yj则属于A区。

为了简化算法,其实我们可以约定x0<x<=x1x=xmin(这样更好判断(计算))

function getS(P,Data){ // 为了简化,这里不做P和Data数据检测,默认认为P和Data数据能保证是能得出结果的,即P的x值在区间[Xmin,Xmax];Xmin!=Xmax;Xmin,Xmax是Data中数据X值情况,Data中的数据是预先以x轴排序过的。
    // 返回值,0表示点在折线上,小于0表示属于B区,大于0表示属于A区
    if (P[0]==Data[0][0]) return (P[1]-Data[0][1]); // 特殊处理P的x等于Xmin
    }
    i=0;// 因为后续要用到这个i值,所以不能在for循环中使用let声明定义
    for(;i<(Data.length-1);i++){
        if( Data[i][0]<P[0] && Data[i+1][0]>=P[0]) break; // 取得P对应区间
    }
    if (P[0]==Data[i+1][0] ) return (P[1]-Data[i+1][1]);// 特殊处理,P的x值是点集中某个x值情况。
    yj = ( P[0]-Data[i][0])*(Data[i+1][1]-Data[i][1])/(Data[i+1][0]-Data[i][0]) + Data[i][1]; //利用直线方程求得对应交点y值
    return (P[1]-yj) ;
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题