点在2点定义的线上的投影

Chr*_*zio 5 c# geometry

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

要解决的问题

说我有3分。

P1 ---------- P2, and P3 can be anywhere around P1 and P2
Run Code Online (Sandbox Code Playgroud)

将P3插值到P1和P2之间的直线上要计算的公式是什么?

我需要一个公式来计算P3和P1之间的直线的新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);
        }
Run Code Online (Sandbox Code Playgroud)

和我的参考。.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();
        }
Run Code Online (Sandbox Code Playgroud)

Cor*_*urn 5

这是一些我们在工作中(一家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;
}
Run Code Online (Sandbox Code Playgroud)

line1是一个经度和纬度的点,代表该线的端点之一,与P1等效。line2是另一个端点:P2。pt是您的P3。这将返回P3垂直穿过的线上的点。如果P3在行的任何一端之后,则将返回null,这意味着两个端点之一是最接近P3的点。

为了清楚起见:

在此处输入图片说明