确定一个点是否位于由给定纬度/经度的 3 个点组成的三角形内

发布于 2024-08-25 03:51:52 字数 53 浏览 5 评论 0原文

我有 3 个点( lat , lon )形成一个三角形。我如何找到一个点是否在这个三角形内?

I have 3 points ( lat , lon ) that form a triangle.How can i find if a point is inside this triangle?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

雅心素梦 2024-09-01 03:51:52

Java 代码只是三角形,即 3 个点。

    public static boolean pntInTriangle(double px, double py, double x1, double y1, double x2, double y2, double x3, double y3) {

    double o1 = getOrientationResult(x1, y1, x2, y2, px, py);
    double o2 = getOrientationResult(x2, y2, x3, y3, px, py);
    double o3 = getOrientationResult(x3, y3, x1, y1, px, py);

    return (o1 == o2) && (o2 == o3);
}

private static int getOrientationResult(double x1, double y1, double x2, double y2, double px, double py) {
    double orientation = ((x2 - x1) * (py - y1)) - ((px - x1) * (y2 - y1));
    if (orientation > 0) {
        return 1;
    }
    else if (orientation < 0) {
        return -1;
    }
    else {
        return 0;
    }
}

Java Code for just triangle , that is 3 points.

    public static boolean pntInTriangle(double px, double py, double x1, double y1, double x2, double y2, double x3, double y3) {

    double o1 = getOrientationResult(x1, y1, x2, y2, px, py);
    double o2 = getOrientationResult(x2, y2, x3, y3, px, py);
    double o3 = getOrientationResult(x3, y3, x1, y1, px, py);

    return (o1 == o2) && (o2 == o3);
}

private static int getOrientationResult(double x1, double y1, double x2, double y2, double px, double py) {
    double orientation = ((x2 - x1) * (py - y1)) - ((px - x1) * (y2 - y1));
    if (orientation > 0) {
        return 1;
    }
    else if (orientation < 0) {
        return -1;
    }
    else {
        return 0;
    }
}
始于初秋 2024-09-01 03:51:52

这是重心坐标解决方案的 Javascript 实现此处讨论

// Returns true if point P inside the triangle with vertices at A, B and C
// representing 2D vectors and points as [x,y]. Based on                        
// http://www.blackpawn.com/texts/pointinpoly/default.html
function pointInTriange(P, A, B, C) {
  // Compute vectors        
  function vec(from, to) {  return [to[0] - from[0], to[1] - from[1]];  }
  var v0 = vec(A, C);
  var v1 = vec(A, B);
  var v2 = vec(A, P);
  // Compute dot products
  function dot(u, v) {  return u[0] * v[0] + u[1] * v[1];  }
  var dot00 = dot(v0, v0);
  var dot01 = dot(v0, v1);
  var dot02 = dot(v0, v2);
  var dot11 = dot(v1, v1);
  var dot12 = dot(v1, v2);
  // Compute barycentric coordinates
  var invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01);
  var u = (dot11 * dot02 - dot01 * dot12) * invDenom;
  var v = (dot00 * dot12 - dot01 * dot02) * invDenom;
  // Check if point is in triangle
  return (u >= 0) && (v >= 0) && (u + v < 1);
}

据说速度更快比基于跨产品的解决方案。

Here's a Javascript implementation of the barycentric coordinates solution discussed here:

// Returns true if point P inside the triangle with vertices at A, B and C
// representing 2D vectors and points as [x,y]. Based on                        
// http://www.blackpawn.com/texts/pointinpoly/default.html
function pointInTriange(P, A, B, C) {
  // Compute vectors        
  function vec(from, to) {  return [to[0] - from[0], to[1] - from[1]];  }
  var v0 = vec(A, C);
  var v1 = vec(A, B);
  var v2 = vec(A, P);
  // Compute dot products
  function dot(u, v) {  return u[0] * v[0] + u[1] * v[1];  }
  var dot00 = dot(v0, v0);
  var dot01 = dot(v0, v1);
  var dot02 = dot(v0, v2);
  var dot11 = dot(v1, v1);
  var dot12 = dot(v1, v2);
  // Compute barycentric coordinates
  var invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01);
  var u = (dot11 * dot02 - dot01 * dot12) * invDenom;
  var v = (dot00 * dot12 - dot01 * dot02) * invDenom;
  // Check if point is in triangle
  return (u >= 0) && (v >= 0) && (u + v < 1);
}

It's said to be faster than the cross-product based solutions.

风启觞 2024-09-01 03:51:52

您可以使用点多边形测试。

这很简单。从你的点到东画一条线,距离足够远。计算该线与您的多边形相交的次数。如果是偶数,你的点就在外面,如果是奇数,你的点就在里面。

这适用于任何类型的多边形。

You can use point-polygon test.

It's simple. Draw a line from your point to East for a big enough distance. Count the number of times that line intersects with your plygon. If it's even, your point is outside, if odd, its inside.

That works for any type of polygon.

客…行舟 2024-09-01 03:51:52

大多数语言都包含此功能。在 Java 中是 Polygon.contains()
http://docs.oracle.com/javase/ 7/docs/api/java/awt/Polygon.html

只需从您的点创建一个多边形,然后在您的测试点上调用 contains() 即可。

Most languages include a function for this. In Java it's Polygon.contains()
http://docs.oracle.com/javase/7/docs/api/java/awt/Polygon.html

Simply create a polygon from your points, and then call contains() on your test point.

十雾 2024-09-01 03:51:52

主要问题是您是否可以为此使用二维近似(换句话说,您的三角形是否足够小)。

如果是这样,像重心坐标这样的简单东西就可以很好地工作。

The main question is whether you can use a 2D approximation for this (in other words, is your triangle small enough).

If so, something simple like barycentric coordinates will work well.

梦里寻她 2024-09-01 03:51:52

尝试光线投射算法。

http://en.wikipedia.org/wiki/Point_in_polygon

实现起来非常简单。

Try the ray casting algorithm.

http://en.wikipedia.org/wiki/Point_in_polygon

It is pretty simple to implement.

等风也等你 2024-09-01 03:51:52
function SameSide(p1,p2, a,b)
    cp1 = CrossProduct(b-a, p1-a)
    cp2 = CrossProduct(b-a, p2-a)
    if DotProduct(cp1, cp2) >= 0 then return true
    else return false

function PointInTriangle(p, a,b,c)
    if SameSide(p,a, b,c) and SameSide(p,b, a,c)
        and SameSide(p,c, a,b) then return true
    else return false

在下面的链接中进行了解释

http://www.blackpawn.com/texts/pointinpoly/default .html

function SameSide(p1,p2, a,b)
    cp1 = CrossProduct(b-a, p1-a)
    cp2 = CrossProduct(b-a, p2-a)
    if DotProduct(cp1, cp2) >= 0 then return true
    else return false

function PointInTriangle(p, a,b,c)
    if SameSide(p,a, b,c) and SameSide(p,b, a,c)
        and SameSide(p,c, a,b) then return true
    else return false

Explained at the link below

http://www.blackpawn.com/texts/pointinpoly/default.html

小猫一只 2024-09-01 03:51:52

我今天就做了这样的事!还有(lat,lon),实际上是(theta,phi),尽管我对我正在使用的网格了解更多。我正在使用 (theta, phi) 0 <= theta <= PI && 0 <= phi <= 2*PI。

您会发现,如果其中一个顶点位于球体的顶部或底部,您可能会遇到一些麻烦,因为在我的情况下 phi 并未真正定义。你最终会在那里得到一个奇点。基本上你已经得到了一个正方形,这样可以更轻松地检查你的点是否位于其中。

在所有其他情况下,如果您已将点转换为 (lat, lon) / (theta, phi)。只需使用@Michelle Six 描述的方法应该很简单。

I've done something like this today! Also with (lat, lon), actually (theta, phi), although I knew a little more about the mesh I was working with. I'm working with (theta, phi) with 0 <= theta <= PI && 0 <= phi <= 2*PI.

You'll find that you might have some trouble if one of the vertices is at the top or bottom of your sphere, since in my case phi isn't really defined. You end up with a singularity there. You've basically got a square, which makes it easier to check whether your point lies within it or not.

In all other cases, if you've converted your point into (lat, lon) / (theta, phi). It should be simple to just use the method as described by @Michelle Six.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文