我想设计一个可以生成各种“地图”的函数。
例如:
创建位置A,它位于某个位置X
创建位置B,它位于某个位置Y,我们知道X,Y之间的距离
创建位置C,我们知道从C到B的距离,我们如何计算C到A?
使用三角形方法,我想我也可以指定一个随机角度并计算第三面,但如果我随机添加了一个位置D,E,F怎么办?我会计算多个三角形,每增加一个指数会变得更糟吗?
答案 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)
是的,你添加的每个点在几何上都会变得更复杂。
问题在于,即使您知道三角形的所有三个边的长度,您仍然不知道方向。为了说明你的例子:
您通过指定距离dAB和dBC(为您提供dAC)来定义ABC。但实际上你有两个可能的三角形,ABC和ABC'。这意味着如果你添加第四个点D,通过指定它与ABC上一个点的距离(例如dCD),你添加了一个第二个三角形,它也可以有两个方向中的一个,总共四个可能的解决方案。如您所见,方向对于确定同一三角形上两点之间的距离无关紧要,但是对于确定不同三角形上的点之间的距离,确实如此。