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

时间:2010-03-17 18:35:36

标签: javascript geometry geolocation

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

8 个答案:

答案 0 :(得分:5)

只有三角形的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;
    }
}

答案 1 :(得分:3)

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

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

答案 2 :(得分:3)

以下是重心坐标解discussed here的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);
}
据说它比基于交叉产品的解决方案更快。

答案 3 :(得分:2)

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

这很简单。从你的点到东方画一条线,足够大的距离。计算该线与您的plygon相交的次数。如果它是偶数,你的观点是在外面,如果是奇数,它的内部。

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

答案 4 :(得分:1)

主要问题是你是否可以使用2D近似(换句话说,你的三角形是否足够小)。

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

答案 5 :(得分:0)

尝试光线投射算法。

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

实施起来非常简单。

答案 6 :(得分:0)

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

答案 7 :(得分:0)

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

你会发现如果其中一个顶点位于球体的顶部或底部,你可能会遇到麻烦,因为在我的情况下,phi并没有真正定义。你最终会有一个奇点。你基本上有一个正方形,这样可以更容易地检查你的观点是否在其中。

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

相关问题