我试图检查点的位置,并检测它们是否在一条线上,然后输出包含可能的线的对象。 问题:
- 这是做的最好的方法是什么? 高效的具有四个循环?
- 我也越来越重复的双回路内的匹配点,什么是去除那些最好的方法是什么?
- 如果我想检测的形状,例如正方形(90度角),等边三角形(60度角)等,我将如何延伸呢?
- 如果我想要做的在点数据,例如一个点图案先进的检测在90度是1公里,在100度的一个点是1.5公里,在110公里一个点为2km等匹配将是:每5度的距离的增加通过+50公里。 我怎么能实现呢?
这是在那里我得到了一个js小提琴:
http://jsfiddle.net/kmturley/RAQXf/1/
我们知道,1点的长和纬度坐标 - 5.我们要计算它们之间的红线。
起点数据:
var points = [
{
name: 'Point 1',
lat: 51.509440,
long: -0.126985
},
{
name: 'Point 2',
lat: 51.509453,
long: -0.126180
},
{
name: 'Point 3',
lat: 51.510076,
long: -0.124804
},
{
name: 'Point 4',
lat: 51.510327,
long: -0.124133
},
{
name: 'Point 5',
lat: 51.509440,
long: -0.124175
}
];
下面是我使用的功能:
var utils = {
distHaversine: function (lon1, lat1, lon2, lat2) { // calculate distance between two points
var R = 6371; // earth's mean radius in km
var dLat = this.toRad(lat2 - lat1);
var dLon = this.toRad(lon2 - lon1);
lat1 = this.toRad(lat1),
lat2 = this.toRad(lat2);
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d;
},
bearing: function (lon1, lat1, lon2, lat2) { // calculate bearing between two points
lat1 = this.toRad(lat1);
lat2 = this.toRad(lat2);
var dLon = this.toRad(lon2 - lon1);
var y = Math.sin(dLon) * Math.cos(lat2);
var x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);
return this.toBrng(Math.atan2(y, x));
},
toRad: function (val) { // convert degrees to radians
return val * Math.PI / 180;
},
toDeg: function (val) { // convert radians to degrees (signed)
return val * 180 / Math.PI;
},
toBrng: function (val) { // convert radians to degrees (as bearing: 0...360)
return (this.toDeg(val) + 360) % 360;
}
};
这是据我已经得到了:
function calculate(items) {
var i = 0,
j = 0,
accuracy = 2,
bearings = {};
// loop through the points and check the distance and bearing of each one
for (i = 0; i < items.length; i += 1) {
for (j = 0; j < items.length; j += 1) {
if (i !== j) {
var bearing = utils.bearing(items[i].long, items[i].lat, items[j].long, items[j].lat);
var distance = utils.distHaversine(items[i].long, items[i].lat, items[j].long, items[j].lat);
var key = Math.round(bearing / accuracy) * accuracy;
// push both points into the bearing array for the same line
if (!bearings[key]) { bearings[key] = {}; }
bearings[key][i] = true;
bearings[key][j] = true;
console.log(Math.round(distance * 1000) + 'm', Math.round(bearing) + '°', items[i].name + ' > ' + items[j].name);
}
}
}
return bearings;
}
function lines(bearings, items) {
var item = {},
key = '',
lines = [];
// loop though the bearings and create lines
for (item in bearings) {
if (utils.size(bearings[item]) > 2) {
var line = { name: 'Line ' + item + '°', points: [] };
for (key in bearings[item]) {
line.points.push(items[parseInt(key)]);
}
lines.push(line);
}
}
return lines;
}
var bearings = calculate(points);
var lines = lines(bearings, points);
console.log('--------');
console.log(lines);
预期输出:
var lines = [
{
name: 'Line 1',
points: [
{
name: 'Point 1',
lat: 51.509440,
long: -0.126985
},
{
name: 'Point 2',
lat: 51.509453,
long: -0.126180
},
{
name: 'Point 5',
lat: 51.509440,
long: -0.124175
}
]
},
{
name: 'Line 2',
points: [
{
name: 'Point 2',
lat: 51.509453,
long: -0.126180
},
{
name: 'Point 3',
lat: 51.510076,
long: -0.124804
},
{
name: 'Point 4',
lat: 51.510327,
long: -0.124133
}
]
}
];
这是在那里我得到了一个js小提琴:
http://jsfiddle.net/kmturley/RAQXf/1/