我需要C#解决方案来解决我在Javascript中拥有的某些代码,该代码需要一组形成区域或区域的纬度和经度位置。以及对象X和Y的位置,并返回距对象最近点的X和Y。这段代码在Javascript中可以完美地工作,但是由于我现在正在用C#重写我的工作,因此我无法找到一个可行的解决方案,该解决方案可以执行此功能。
下面是Javascript函数,它带有2个参数pXy(这是您所在位置的X和Y位置)和aXys(这是X和Y位置组成的数组的折线)。
var getClosestPointOnLines = function(pXy, aXys) {
var minDist;
var fTo;
var fFrom;
var x;
var y;
var i;
var dist;
if (aXys.length > 1) {
for (var n = 1 ; n < aXys.length ; n++) {
if (aXys[n].x != aXys[n - 1].x) {
var a = (aXys[n].y - aXys[n - 1].y) / (aXys[n].x - aXys[n - 1].x);
var b = aXys[n].y - a * aXys[n].x;
dist = Math.abs(a * pXy.x + b - pXy.y) / Math.sqrt(a * a + 1);
}
else
dist = Math.abs(pXy.x - aXys[n].x)
// length^2 of line segment
var rl2 = Math.pow(aXys[n].y - aXys[n - 1].y, 2) + Math.pow(aXys[n].x - aXys[n - 1].x, 2);
// distance^2 of pt to end line segment
var ln2 = Math.pow(aXys[n].y - pXy.y, 2) + Math.pow(aXys[n].x - pXy.x, 2);
// distance^2 of pt to begin line segment
var lnm12 = Math.pow(aXys[n - 1].y - pXy.y, 2) + Math.pow(aXys[n - 1].x - pXy.x, 2);
// minimum distance^2 of pt to infinite line
var dist2 = Math.pow(dist, 2);
// calculated length^2 of line segment
var calcrl2 = ln2 - dist2 + lnm12 - dist2;
// redefine minimum distance to line segment (not infinite line) if necessary
if (calcrl2 > rl2)
dist = Math.sqrt(Math.min(ln2, lnm12));
if ((minDist == null) || (minDist > dist)) {
if (calcrl2 > rl2) {
if (lnm12 < ln2) {
fTo = 0;//nearer to previous point
fFrom = 1;
}
else {
fFrom = 0;//nearer to current point
fTo = 1;
}
}
else {
// perpendicular from point intersects line segment
fTo = ((Math.sqrt(lnm12 - dist2)) / Math.sqrt(rl2));
fFrom = ((Math.sqrt(ln2 - dist2)) / Math.sqrt(rl2));
}
minDist = dist;
i = n;
}
}
var dx = aXys[i - 1].x - aXys[i].x;
var dy = aXys[i - 1].y - aXys[i].y;
x = aXys[i - 1].x - (dx * fTo);
y = aXys[i - 1].y - (dy * fTo);
}
return { 'x': x, 'y': y, 'i': i, 'fTo': fTo, 'fFrom': fFrom };
}
如何在C#中复制以上内容?
答案 0 :(得分:0)
感谢xdtTransform。我没有使用Visual Studio,所以没有意识到Ctrl + Space。安装后,我已经设法自己转换了代码。我已将其包含在此处,以供将来从中受益的任何人。
我从一堂课开始,掌握了这些点的纬度和经度详细信息。
namespace Classes
{
public class AppGeoPoint
{
public double X { get; set; }
public double Y { get; set; }
}
}
然后将函数转换为
public static Classes.AppGeoPoint getClosestPointOnLines(Classes.AppGeoPoint pXy, Classes.AppGeoPoint[] aXys)
{
double? minDist = null;
double fTo = 0.0;
double fFrom;
double x = 0.0;
double y = 0.0;
int i = 0;
double dist;
if (aXys.Length > 1)
{
for (var n = 1; n < aXys.Length; n++)
{
if (aXys[n].X != aXys[n - 1].X)
{
var a = (aXys[n].Y - aXys[n - 1].Y) / (aXys[n].X - aXys[n - 1].X);
var b = aXys[n].Y - a * aXys[n].X;
dist = Math.Abs(a * pXy.X + b - pXy.Y) / Math.Sqrt(a * a + 1);
}
else
dist = Math.Abs(pXy.X - aXys[n].X);
// length^2 of line segment
double rl2 = Math.Pow(aXys[n].Y - aXys[n - 1].Y, 2) + Math.Pow(aXys[n].X - aXys[n - 1].X, 2);
// distance^2 of pt to end line segment
double ln2 = Math.Pow(aXys[n].Y - pXy.Y, 2) + Math.Pow(aXys[n].X - pXy.X, 2);
// distance^2 of pt to begin line segment
double lnm12 = Math.Pow(aXys[n - 1].Y - pXy.Y, 2) + Math.Pow(aXys[n - 1].X - pXy.X, 2);
// minimum distance^2 of pt to infinite line
double dist2 = Math.Pow(dist, 2);
// calculated length^2 of line segment
double calcrl2 = ln2 - dist2 + lnm12 - dist2;
// redefine minimum distance to line segment (not infinite line) if necessary
if (calcrl2 > rl2)
dist = Math.Sqrt(Math.Min(ln2, lnm12));
if ((minDist == null) || (minDist > dist))
{
if (calcrl2 > rl2)
{
if (lnm12 < ln2)
{
fTo = 0;//nearer to previous point
fFrom = 1;
}
else
{
fFrom = 0;//nearer to current point
fTo = 1;
}
}
else
{
// perpendicular from point intersects line segment
fTo = ((Math.Sqrt(lnm12 - dist2)) / Math.Sqrt(rl2));
fFrom = ((Math.Sqrt(ln2 - dist2)) / Math.Sqrt(rl2));
}
minDist = dist;
i = n;
}
}
var dx = aXys[i - 1].X - aXys[i].X;
var dy = aXys[i - 1].Y - aXys[i].Y;
x = aXys[i - 1].X - (dx * fTo);
y = aXys[i - 1].Y - (dy * fTo);
}
return new Classes.AppGeoPoint { X = x, Y = y };
}
然后,最后,构建一个数组列表并检查最接近的点
Classes.AppGeoPoint YourLocation= new Classes.AppGeoPoint { X = 50.83737, Y = -1.07428 };
Classes.AppGeoPoint[] AreaCheck = new[] {
new Classes.AppGeoPoint { X = 50.847550000000005, Y = -1.0863200000000002 },
new Classes.AppGeoPoint { X = 50.83975, Y = -1.0859800000000002 },
new Classes.AppGeoPoint { X = 50.83845, Y = -1.06487 },
new Classes.AppGeoPoint { X = 50.84723, Y = -1.0645200000000001 }
};
Classes.AppGeoPoint ReturnVal = getClosestPointOnLines(YourLocation, AreaCheck);
Console.WriteLine("X " + ReturnVal.X);
Console.WriteLine("Y " + ReturnVal.Y);
ReturnVal.X和ReturnVal.Y将返回最接近的点的纬度和经度。
希望这对其他人有帮助。