如何在javascript中生成彼此之间距离的随机位置?

时间:2012-11-10 06:02:27

标签: javascript node.js maps

我想设计一个可以生成各种“地图”的函数。

例如:

创建位置A,它位于某个位置X

创建位置B,它位于某个位置Y,我们知道X,Y之间的距离

创建位置C,我们知道从C到B的距离,我们如何计算C到A?

使用三角形方法,我想我也可以指定一个随机角度并计算第三面,但如果我随机添加了一个位置D,E,F怎么办?我会计算多个三角形,每增加一个指数会变得更糟吗?

3 个答案:

答案 0 :(得分:1)

假设您要生成位置列表L[1..n],您只需随机选择下一个位置并扫描L以确保距离超过阈值,否则,再次选择。

然后,将其推入列表L。因此,生成n个元素列表的总运行时间是O(n ^ 2)。当n < 1000,这足够快。保证终止以下方法,该方法适用于相对较小的读取选择列表,例如高达1,000,000。

function generateList(orgList, numberToOutput) {
  if (orgList.length < numberToOutput)
    return false;
  var orgListClone = orgList.slice(0);
  var L = [];
  while (L.length < numberToOutput && orgListClone.length > 0) {
    var n = parseInt(Math.random() * orgListClone.length);
    // Assume we pick n-th element in the list.
    var ok = true;
    for (var j = 0; j < L.length; j++)
      if (distance(orgListClone[n], L[j]) < kThreshold) {
        // n is not an option, swap orgListClone[n] with the last element and pop it out.
        orgListClone[n] = orgListClone[orgListClone.length - 1];
        orgListClone.pop();
        ok = false;
        break;
      }
    if (ok) {
      // All tests passed
      L.push(orgListClone[n]);
      orgListClone[n] = orgListClone[orgListClone.length - 1];
      orgListClone.pop();
    }
  }
  if (L.length == numberToOutput)
    return L;
  // Failed to find the list
  return null;
}

另一个解决方案是计算前方每个位置之间的距离,并为每个位置列出太近的位置。

因此,在每次选择之后,只需将太近的位置合并到当前集合,这需要O(n)。然后选择另一个未包含在此集合中的位置。此方法仅在读取选择列表足够大时才有效,因此选择未包含在集合中的位置的概率(1 - |too close list| / |read-to-pick list|)很大。这总共需要O(nm),其中m是平均值太接近的列表。

function generateList(orgList, numberToOutput) {
  if (orgList.length < numberToOutput)
    return false;
  var tooCloseSet = {};
  var L = [];
  var lastLengthOfL = 0;
  var repickCount = 0;
  for (L.length < numberToOutput) {
    if (l.length == lastLengthOfL) {
      if (++repickCount > 10)
        return false;
    } else {
      lastLengthOfL = l.length;
      repickCount = 0;
    }
    var n = parseInt(Math.random() * orgList.length);
    if (n in tooCloseSet)
      continue;
    L.push(orgList[n]);
    mergeSet(tooCloseSet, orgList[n].tooCloseList);
  }
  return L;
}

答案 1 :(得分:0)

你可以试试这样的东西,我还没有测试过,所以这只是概念性的。

你可以生成一个随机放置点的数组,每个点都可以保存它自己的距离数组,使用基本的三角函数计算。

function Point(x, y) {
  return {
    x: x, 
    y:y, 
    addRelative: function(pt) {
       this.realtivePoints[pt] = abs(sqrt(pow((this.x-pt.x),2) + pow((this.y-pt.y),2)));
    },
    relativePoints: {}
};

var randPoints = []; // Lets assume this has a collection of random Point objects

for(var i=0; i<randPoints.length; i++) {
  for(var j=0; j<randPoints.length; j++) {
    randPoint[i].addRelative(randPoints[j]);
  }
}

randPoints[0].relativePoints[randPoints[1]]; // Dist from first to second point.

答案 2 :(得分:0)

是的,你添加的每个点在几何上都会变得更复杂。

问题在于,即使您知道三角形的所有三个边的长度,您仍然不知道方向。为了说明你的例子:

enter image description here

您通过指定距离dAB和dBC(为您提供dAC)来定义ABC。但实际上你有两个可能的三角形,ABC和ABC'。这意味着如果你添加第四个点D,通过指定它与ABC上一个点的距离(例如dCD),你添加了一个第二个三角形,它也可以有两个方向中的一个,总共四个可能的解决方案。如您所见,方向对于确定同一三角形上两点之间的距离无关紧要,但是对于确定不同三角形上的点之间的距离,确实如此。