我一直在设法解决这个问题。

要解决的问题

说我有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/

10-11 06:00