Merge pull request #1550 from twpayne/closest-point-interpolation
Preserve extra dimensions in closest point calculations
This commit is contained in:
@@ -94,7 +94,7 @@ ol.format.IGC.prototype.readFeatureFromText = function(text) {
|
||||
var properties = {};
|
||||
var flatCoordinates = [];
|
||||
var year = 2000;
|
||||
var month = 1;
|
||||
var month = 0;
|
||||
var day = 1;
|
||||
var i, ii;
|
||||
for (i = 0, ii = lines.length; i < ii; ++i) {
|
||||
@@ -134,7 +134,7 @@ ol.format.IGC.prototype.readFeatureFromText = function(text) {
|
||||
m = ol.format.IGC.HFDTE_RECORD_RE_.exec(line);
|
||||
if (m) {
|
||||
day = parseInt(m[1], 10);
|
||||
month = parseInt(m[2], 10);
|
||||
month = parseInt(m[2], 10) - 1;
|
||||
year = 2000 + parseInt(m[3], 10);
|
||||
} else {
|
||||
m = ol.format.IGC.H_RECORD_RE_.exec(line);
|
||||
|
||||
@@ -39,21 +39,24 @@ ol.geom.Circle.prototype.clone = function() {
|
||||
ol.geom.Circle.prototype.closestPointXY =
|
||||
function(x, y, closestPoint, minSquaredDistance) {
|
||||
var flatCoordinates = this.flatCoordinates;
|
||||
var radius = flatCoordinates[this.stride] - flatCoordinates[0];
|
||||
var dx = x - flatCoordinates[0];
|
||||
var dy = y - flatCoordinates[1];
|
||||
var d = Math.sqrt(dx * dx + dy * dy);
|
||||
var distance = Math.max(d, 0);
|
||||
var squaredDistance = distance * distance;
|
||||
var squaredDistance = dx * dx + dy * dy;
|
||||
if (squaredDistance < minSquaredDistance) {
|
||||
if (d === 0) {
|
||||
closestPoint[0] = flatCoordinates[0];
|
||||
closestPoint[1] = flatCoordinates[1];
|
||||
var i;
|
||||
if (squaredDistance === 0) {
|
||||
for (i = 0; i < this.stride; ++i) {
|
||||
closestPoint[i] = flatCoordinates[i];
|
||||
}
|
||||
} else {
|
||||
var delta = radius / d;
|
||||
var delta = this.getRadius() / Math.sqrt(squaredDistance);
|
||||
closestPoint[0] = flatCoordinates[0] + delta * dx;
|
||||
closestPoint[1] = flatCoordinates[1] + delta * dy;
|
||||
for (i = 2; i < this.stride; ++i) {
|
||||
closestPoint[i] = flatCoordinates[i];
|
||||
}
|
||||
}
|
||||
closestPoint.length = this.stride;
|
||||
return squaredDistance;
|
||||
} else {
|
||||
return minSquaredDistance;
|
||||
|
||||
@@ -95,14 +95,16 @@ ol.geom.closest.getClosestPoint = function(flatCoordinates, offset, end, stride,
|
||||
if (offset == end) {
|
||||
return minSquaredDistance;
|
||||
}
|
||||
var squaredDistance;
|
||||
var i, squaredDistance;
|
||||
if (maxDelta === 0) {
|
||||
// All points are identical, so just test the first point.
|
||||
squaredDistance = ol.geom.flat.squaredDistance(
|
||||
x, y, flatCoordinates[offset], flatCoordinates[offset + 1]);
|
||||
if (squaredDistance < minSquaredDistance) {
|
||||
closestPoint[0] = flatCoordinates[offset];
|
||||
closestPoint[1] = flatCoordinates[offset + 1];
|
||||
for (i = 0; i < stride; ++i) {
|
||||
closestPoint[i] = flatCoordinates[offset + i];
|
||||
}
|
||||
closestPoint.length = stride;
|
||||
return squaredDistance;
|
||||
} else {
|
||||
return minSquaredDistance;
|
||||
@@ -112,15 +114,16 @@ ol.geom.closest.getClosestPoint = function(flatCoordinates, offset, end, stride,
|
||||
var tmpPoint = goog.isDef(opt_tmpPoint) ? opt_tmpPoint : [NaN, NaN];
|
||||
var index = offset + stride;
|
||||
while (index < end) {
|
||||
ol.geom.flat.closestPoint(x, y,
|
||||
flatCoordinates[index - stride], flatCoordinates[index - stride + 1],
|
||||
flatCoordinates[index], flatCoordinates[index + 1], tmpPoint);
|
||||
ol.geom.flat.closestPoint(
|
||||
flatCoordinates, index - stride, index, stride, x, y, tmpPoint);
|
||||
squaredDistance = ol.geom.flat.squaredDistance(
|
||||
x, y, tmpPoint[0], tmpPoint[1]);
|
||||
if (squaredDistance < minSquaredDistance) {
|
||||
minSquaredDistance = squaredDistance;
|
||||
closestPoint[0] = tmpPoint[0];
|
||||
closestPoint[1] = tmpPoint[1];
|
||||
for (i = 0; i < stride; ++i) {
|
||||
closestPoint[i] = tmpPoint[i];
|
||||
}
|
||||
closestPoint.length = stride;
|
||||
index += stride;
|
||||
} else {
|
||||
// Skip ahead multiple points, because we know that all the skipped
|
||||
@@ -140,15 +143,16 @@ ol.geom.closest.getClosestPoint = function(flatCoordinates, offset, end, stride,
|
||||
}
|
||||
if (isRing) {
|
||||
// Check the closing segment.
|
||||
ol.geom.flat.closestPoint(x, y,
|
||||
flatCoordinates[end - stride], flatCoordinates[end - stride + 1],
|
||||
flatCoordinates[offset], flatCoordinates[offset + 1], tmpPoint);
|
||||
ol.geom.flat.closestPoint(
|
||||
flatCoordinates, end - stride, offset, stride, x, y, tmpPoint);
|
||||
squaredDistance = ol.geom.flat.squaredDistance(
|
||||
x, y, tmpPoint[0], tmpPoint[1]);
|
||||
if (squaredDistance < minSquaredDistance) {
|
||||
minSquaredDistance = squaredDistance;
|
||||
closestPoint[0] = tmpPoint[0];
|
||||
closestPoint[1] = tmpPoint[1];
|
||||
for (i = 0; i < stride; ++i) {
|
||||
closestPoint[i] = tmpPoint[i];
|
||||
}
|
||||
closestPoint.length = stride;
|
||||
}
|
||||
}
|
||||
return minSquaredDistance;
|
||||
|
||||
@@ -2,39 +2,50 @@ goog.provide('ol.geom.flat');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.math');
|
||||
goog.require('goog.vec.Mat4');
|
||||
|
||||
|
||||
/**
|
||||
* Returns the point on the line segment (x1, y1) to (x2, y2) that is closest to
|
||||
* the point (x, y).
|
||||
* Returns the point on the 2D line segment flatCoordinates[offset1] to
|
||||
* flatCoordinates[offset2] that is closest to the point (x, y). Extra
|
||||
* dimensions are linearly interpolated.
|
||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||
* @param {number} offset1 Offset 1.
|
||||
* @param {number} offset2 Offset 2.
|
||||
* @param {number} stride Stride.
|
||||
* @param {number} x X.
|
||||
* @param {number} y Y.
|
||||
* @param {number} x1 X1.
|
||||
* @param {number} y1 Y1.
|
||||
* @param {number} x2 X2.
|
||||
* @param {number} y2 Y2.
|
||||
* @param {Array.<number>} closestPoint Closest point.
|
||||
*/
|
||||
ol.geom.flat.closestPoint = function(x, y, x1, y1, x2, y2, closestPoint) {
|
||||
var dx = x2 - x1;
|
||||
var dy = y2 - y1;
|
||||
ol.geom.flat.closestPoint =
|
||||
function(flatCoordinates, offset1, offset2, stride, x, y, closestPoint) {
|
||||
var x1 = flatCoordinates[offset1];
|
||||
var y1 = flatCoordinates[offset1 + 1];
|
||||
var dx = flatCoordinates[offset2] - x1;
|
||||
var dy = flatCoordinates[offset2 + 1] - y1;
|
||||
var i, offset;
|
||||
if (dx === 0 && dy === 0) {
|
||||
closestPoint[0] = x1;
|
||||
closestPoint[1] = y1;
|
||||
offset = offset1;
|
||||
} else {
|
||||
var t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);
|
||||
if (t > 1) {
|
||||
closestPoint[0] = x2;
|
||||
closestPoint[1] = y2;
|
||||
offset = offset2;
|
||||
} else if (t > 0) {
|
||||
closestPoint[0] = x1 + dx * t;
|
||||
closestPoint[1] = y1 + dy * t;
|
||||
for (i = 0; i < stride; ++i) {
|
||||
closestPoint[i] = goog.math.lerp(flatCoordinates[offset1 + i],
|
||||
flatCoordinates[offset2 + i], t);
|
||||
}
|
||||
closestPoint.length = stride;
|
||||
return;
|
||||
} else {
|
||||
closestPoint[0] = x1;
|
||||
closestPoint[1] = y1;
|
||||
offset = offset1;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < stride; ++i) {
|
||||
closestPoint[i] = flatCoordinates[offset + i];
|
||||
}
|
||||
closestPoint.length = stride;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -42,14 +42,16 @@ ol.geom.MultiPoint.prototype.closestPointXY =
|
||||
}
|
||||
var flatCoordinates = this.flatCoordinates;
|
||||
var stride = this.stride;
|
||||
var i, ii;
|
||||
var i, ii, j;
|
||||
for (i = 0, ii = flatCoordinates.length; i < ii; i += stride) {
|
||||
var squaredDistance = ol.geom.flat.squaredDistance(
|
||||
x, y, flatCoordinates[i], flatCoordinates[i + 1]);
|
||||
if (squaredDistance < minSquaredDistance) {
|
||||
minSquaredDistance = squaredDistance;
|
||||
closestPoint[0] = flatCoordinates[i];
|
||||
closestPoint[1] = flatCoordinates[i + 1];
|
||||
for (j = 0; j < stride; ++j) {
|
||||
closestPoint[j] = flatCoordinates[i + j];
|
||||
}
|
||||
closestPoint.length = stride;
|
||||
}
|
||||
}
|
||||
return minSquaredDistance;
|
||||
|
||||
@@ -40,8 +40,12 @@ ol.geom.Point.prototype.closestPointXY =
|
||||
var squaredDistance = ol.geom.flat.squaredDistance(
|
||||
x, y, flatCoordinates[0], flatCoordinates[1]);
|
||||
if (squaredDistance < minSquaredDistance) {
|
||||
closestPoint[0] = flatCoordinates[0];
|
||||
closestPoint[1] = flatCoordinates[1];
|
||||
var stride = this.stride;
|
||||
var i;
|
||||
for (i = 0; i < stride; ++i) {
|
||||
closestPoint[i] = flatCoordinates[i];
|
||||
}
|
||||
closestPoint.length = stride;
|
||||
return squaredDistance;
|
||||
} else {
|
||||
return minSquaredDistance;
|
||||
|
||||
Reference in New Issue
Block a user