我一直在设法解决这个问题。
要解决的问题
说我有3分。
P1 ---------- P2, and P3 can be anywhere around P1 and P2
将P3插值到P1和P2之间的直线上要计算的公式是什么?
我需要一个公式来计算位于P1和P2之间的直线的P3的新X,Y坐标。
到目前为止我的代码
public Point lerp(Point P0, Point P1, Point P)
{
double y1 = P0.Y + (P1.Y - P0.Y) * ((P.X - P0.X) / (P1.X - P0.X));
double x1 = P.X;
double y2 = P.Y;
double x2 = P0.X + (P1.X - P0.X) * ((P.Y - P0.Y) / (P1.Y - P0.Y));
return new Point((x1 + x2) / 2, (y1 + y2) / 2);
}
和我的引用。
http://en.wikipedia.org/wiki/Linear_interpolation
上面的代码将其关闭,但略有偏离...
这是Corey Ogburn转换后的javascript代码
public Point _pointOnLine(Point pt1, Point pt2, Point pt)
{
bool isValid = false;
var r = new Point(0, 0);
if (pt1.Y == pt2.Y && pt1.X == pt2.X) { pt1.Y -= 0.00001; }
var U = ((pt.Y - pt1.Y) * (pt2.Y - pt1.Y)) + ((pt.X - pt1.X) * (pt2.X - pt1.X));
var Udenom = Math.Pow(pt2.Y - pt1.Y, 2) + Math.Pow(pt2.X - pt1.X, 2);
U /= Udenom;
r.Y = pt1.Y + (U * (pt2.Y - pt1.Y));
r.X = pt1.X + (U * (pt2.X - pt1.X));
double minx, maxx, miny, maxy;
minx = Math.Min(pt1.X, pt2.X);
maxx = Math.Max(pt1.X, pt2.X);
miny = Math.Min(pt1.Y, pt2.Y);
maxy = Math.Max(pt1.Y, pt2.Y);
isValid = (r.X >= minx && r.X <= maxx) && (r.Y >= miny && r.Y <= maxy);
return isValid ? r : new Point();
}
最佳答案
这是我们在工作中(一家GIS公司)在这里使用的一些javascript代码,用于在用户想要通过添加顶点来分割线的情况下,找出鼠标所靠近的线的最近点。应该很容易转移到C#:
function _pointOnLine(line1, line2, pt) {
var isValid = false;
var r = new Microsoft.Maps.Location(0, 0);
if (line1.latitude == line2.latitude && line1.longitude == line2.longitude) line1.latitude -= 0.00001;
var U = ((pt.latitude - line1.latitude) * (line2.latitude - line1.latitude)) + ((pt.longitude - line1.longitude) * (line2.longitude - line1.longitude));
var Udenom = Math.pow(line2.latitude - line1.latitude, 2) + Math.pow(line2.longitude - line1.longitude, 2);
U /= Udenom;
r.latitude = line1.latitude + (U * (line2.latitude - line1.latitude));
r.longitude = line1.longitude + (U * (line2.longitude - line1.longitude));
var minx, maxx, miny, maxy;
minx = Math.min(line1.latitude, line2.latitude);
maxx = Math.max(line1.latitude, line2.latitude);
miny = Math.min(line1.longitude, line2.longitude);
maxy = Math.max(line1.longitude, line2.longitude);
isValid = (r.latitude >= minx && r.latitude <= maxx) && (r.longitude >= miny && r.longitude <= maxy);
return isValid ? r : null;
}
line1
是一个经度和纬度的点,代表该线的端点之一,等效于您的P1。 line2
是另一个端点:P2。 pt
是您的P3。这将返回P3垂直穿过的线上的点。如果P3超出了该行的任一端,则将返回null,这意味着两个端点之一是最接近P3的点。为了清楚起见:
关于c# - 点在2点定义的线上的投影,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15232356/