由2分定义线上点的投影 [英] Projection of a point on line defined by 2 points

查看:103
本文介绍了由2分定义线上点的投影的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



要解决的问题。



p>说我有3分..

  P1 ------------------------------- P2和P3都可以P1和P2之间的任何位置

什么是计算公式以便P3插入P1和P2?



我需要一个计算P3的新X,Y坐标的公式,它落在P1和P2之间的线上。

我的代码截至目前为止。

 公共点lerp(Point P0,Point P1,Point P)
{
double y1 = P0.Y +(P1.Y - P0.Y)*((PX - 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));

返回新点((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.Y,pt2.Y);
maxx = Math.Max(pt1.Y,pt2.Y);

miny = Math.Min(pt1.X,pt2.X);
maxy = Math.Max(pt1.X,pt2.X);

isValid =(r.Y> = minx& r.Y< = maxx)&& (r.X> = miny& r.X< = maxy);

返回isValid? r:new Point();


解决方案

在这里用于工作(一家地理信息系统公司)在用户想要通过添加顶点来分割线的情况下找出鼠标所在的线上最近的点。应该很容易移到C#中:

pre $函数_pointOnLine(line1,line2,pt){
var isValid =假;

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 。经度));

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);

返回isValid? r:null;

line1 是一个用经度和纬度来表示该线的一个端点,相当于你的P1。 line2 是另一个端点:P2。 pt 是你的P3。这将返回P3垂直通过的线上的点。如果P3超过该行的任何一端,这将返回null,这意味着两个端点中的一个是最接近P3的点。



为了清楚起见, p>


I have been trying to figure this out for sometime now..

The problem to solve..

Say I have 3 Points..

P1 ---------- P2, and P3 can be anywhere around P1 and P2

What is the formula to calculate so that P3 is interpolated onto the line between P1 and P2?

I need a formula that calculates new X,Y coordinates for P3 that falls on the line between P1 and P2..

My code as of so far..

        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);
        }

And my reference.. http://en.wikipedia.org/wiki/Linear_interpolation

The above code gets it close, but its slightly off...

Here is the converted javascript code from Corey Ogburn

        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.Y, pt2.Y);
            maxx = Math.Max(pt1.Y, pt2.Y);

            miny = Math.Min(pt1.X, pt2.X);
            maxy = Math.Max(pt1.X, pt2.X);

            isValid = (r.Y >= minx && r.Y <= maxx) && (r.X >= miny && r.X <= maxy);

            return isValid ? r : new Point();
        }

解决方案

Here's some javascript code we've used here at work (a GIS company) to figure out the closest point on a line the mouse is next to in a situation where a user wants to split the line by adding a vertex to it. Should be easy to move over to 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 is a point with a latitude and longitude to represent one of the endpoints of the line, equivalent to your P1. line2 is the other endpoint: P2. pt is your P3. This will return the point on the line that P3 is perpendicular through. If P3 is past either end of the line, this will return null which means that one of the two end points is the closest point to P3.

For clarity:

这篇关于由2分定义线上点的投影的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆