确定一组点是否形成近似线

时间:2018-06-10 06:48:21

标签: line curve zigzag

我正在制作线/弧检测算法。 我发现这个令人讨厌的要点:

[(215,69),(217,70),(220,67),(223,65),(226,64),(229,62),(232,60),(236,57) ),(239,56),(242,54),(245,52),(248,50),(251,48),(254,47),(257,45),(260,43), (264,40),(267,39),(270,37),(273,35),(276,33),(279,31),(282,29),(285,28),(288 ,26),(291,24)]

我需要确定这些是形成一条线还是一条曲线。我绘制了集合,它看起来像这样: Set of green points on a line

它们清楚地代表了一条线。

但是,我尝试了各种测试来确定它们是线还是曲线。

  1. 我测试了每个点之间的角度是否近似相等。但是,由于线条有点锯齿,有一些异常点不相等

  2. 我测试了该行的任意3个连续点的叉积,以检查它们是否是共线的

    for k in range(0,len(pts-3),1):
    cp1=pts[k]
    cp2=pts[k+1]
    cp3=pts[k+2]
    c1,c2,c3= (cp1.x,cp1.y),(cp2.x,cp2.y),(cp3.x,cp3.y)
    cros= (p2.x - p1.x)*(p3.y - p1.y) - (p3.x - p1.x)*(p2.y - p1.y)
    print(abs(cros))
    
  3. 其中一些产品具有非常重要的交叉产品。再一次,因为这条线是一条曲折的线,我想。

    这个锯齿状的东西正在抛弃我的算法! 那么如何确定zigged锯齿线是直线还是曲线?

1 个答案:

答案 0 :(得分:0)

假设点基于与线末端的接近度进行排序,我们可以比较每条线与其邻居的梯度,以确定它们是否位于一条线上。关于渐变的好处是我们如何指定容差级别来定义一条线是否过于偏离而不被视为该线的一部分。

JS给定点中的一个例子是一个多维数组:

function calculateIsLine() {
let startingGradient=getGradientFromPoint(0);//we get a baseline and compare to every other point. If it is for example, inverted or completely off,
//we can confirm it doesn't line up.

console.log("Starting Gradient: "+startingGradient);

for (let i = 0; i < points.length-1; i++) {//ignoring last point as no point after it.
    if(Math.abs(startingGradient-getGradientFromPoint(i))>0.5){//0.5 is our tolerance level
        console.log("Conflicting Point: "+points[i]+" "+getGradientFromPoint(i));

        return false;
    }

}
return true;

}
function getGradientFromPoint(offset){
    return (points[offset+1][1]-points[offset][1])/(points[offset+1][0]-points[offset][0]);//gradient formula

}

工作代码段

&#13;
&#13;
let points = [];
let pointsString = "[(215, 69), (217, 70), (220, 67), (223, 65), (226, 64), (229, 62), (300, 60), (236, 57), (239, 56), (242, 54), (245, 52), (248, 50), (251, 48), (254, 47), (257, 45), (260, 43), (264, 40), (267, 39), (270, 37), (273, 35), (276, 33), (279, 31), (282, 29), (285, 28), (288, 26), (291, 24)]";

let conflictingPointIndex;

function setup() {
  let canvas = createCanvas(500, 100);
  let arrayPoints = pointsString.split("(");

  arrayPoints.splice(0, 1);

  for (let i = 0; i < arrayPoints.length; i++) {
    arrayPoints[i] = arrayPoints[i].substr(0, arrayPoints[i].indexOf(")")).replace(" ", "");
    let stringPoint = arrayPoints[i].split(",");
    for (let j = 0; j < 2; j++) {
      if (!points[i])
        points[i] = [];
      points[i][j] = parseInt(stringPoint[j]);

    }
  }
  points.sort((p1, p2) => {
    return p1[0] - p2[0];

  });
 // console.log(points);


}
function draw() {
  background(0);
  console.log(calculateIsLine());
  for (let i = 0; i < points.length; i++) {
    if (i === conflictingPointIndex + 1)
      stroke(255, 0, 0);
    else stroke(255);
    point(points[i][0], points[i][1]);
  }
  noLoop();

}

function calculateIsLine() {
  let startingGradient = getGradientFromPoint(0); //we get a baseline and compare to every other point. If it is for example, inverted or completely off,
  //we can confirm it doesn't line up.
  console.log("Starting Gradient: " + startingGradient);
  for (let i = 0; i < points.length - 1; i++) { //ignoring last point as no point after it.
    if (Math.abs(startingGradient - getGradientFromPoint(i)) > 1.6) { //0.5 is our tolerance level
      console.log("Conflicting Point: " + points[i] + " " + getGradientFromPoint(i) + " " + Math.abs(startingGradient - getGradientFromPoint(i)));
      conflictingPointIndex = i;
      return false;
    }

  }
  return true;

}

function getGradientFromPoint(offset) {
  return (points[offset + 1][1] - points[offset][1]) / (points[offset + 1][0] - points[offset][0]); //gradient formula

}
&#13;
<script src="https://github.com/processing/p5.js/releases/download/0.6.1/p5.js"></script>
&#13;
&#13;
&#13;

我无法想到一种用于曲线的方法。但希望你能想到一个与此类似的方法。其他人也可能有关于曲线的解决方案。