代码之家  ›  专栏  ›  技术社区  ›  Matt

查找点是否位于矩形内

  •  3
  • Matt  · 技术社区  · 16 年前

    如果一个点位于一个给定4个点的二维矩形内,该如何查找?

    6 回复  |  直到 8 年前
        1
  •  8
  •   SuperElectric    16 年前

    将该点转换为与矩形对齐的坐标框,然后问题就变成了轴对齐和琐碎的问题。

    如果矩形由以下4个点组成:

    a  b
    c  d
    

    然后得到矩形的“x轴”和“y轴”,如下所示:

    x = Normalize(d-c)
    y = Normalize(a-c)
    

    然后使用x和y作为列构造旋转矩阵:

    r = [ x | y ]
    

    如果使用三维坐标,我们需要一个Z轴:

    z = CrossProduct(x, y)
    r = [ x | y | z ]
    

    从世界坐标到矩形轴对齐坐标的变换矩阵将变为:

    T = [ r^T | -r^T * c ]
        [ 0^T |     1    ]
    

    这里我们选择了左下角C作为本地原点。”r^t“是r转置的。0^t“是一个二维或三维行向量,用零填充。1只是一个。注意,这只是简单的矩形到世界变换的倒数,即

    T^-1 = [ r   | c ]
           [ 0^T | 1 ]
    

    我们可以用t将点转换成轴对齐的坐标。记住用尾随1填充p,因为t是一个齐次矩阵。

    tp = T * p;  // Don't forget to pad p with a trailing 1 before multiplying.
    
    // Checks that p isn't below or to the left of the rectangle.
    for ( int d = 0; d < num_dimensions; ++d ) {
      if ( tp[d] < 0.0 ) {
        return false;
      }
    }
    
    // Checks that p isn't to the right of the rectangle
    double width = Length(d-c);
    if ( tp[0] > width ) {
      return false;
    }
    
    // Checks that p isn't above the rectangle.
    double height = Length(a-c);
    if ( tp[1] > height ) {
      return false;
    }
    
    // p must be inside or on the rectangle.
    return true
    

    如果使用的是三维坐标,请注意上面的内容忽略了转换点tp的局部z值。即使p不在矩形的平面上,上面的行为就好像它被投影到了矩形的表面上。如果要检查共面性,只需事先执行以下操作:

    if ( fabs(tp[2]) > some_small_positive_number ) {
       return false;  // point is out of the rectangle's plane.
    }
    
        2
  •  2
  •   Lolindrath    16 年前

    I think this might answer your question

    • 完全公开-我去德雷克斯大学学习德雷克
        3
  •  0
  •   AndreasT    16 年前

    要使其特定于OpenGL,请执行以下操作:

    我想你的二维矩形是屏幕坐标系!

    第一:

     gluProject (bli, bla, blorp, ...);
    

    从三维到屏幕坐标。

    那么:诺亚的建议。

    只有当你的观点已经是2d;)时才开枪。

        4
  •  0
  •   Qwertie    16 年前

    对于非轴对齐的矩形,使用与一般多边形相同的算法:多边形中的点测试:

    想象一条光线从测试点指向右。测试多边形中的每一条线是否穿过射线。如果偶数条线穿过射线,则该点位于多边形的外部。如果奇数条线穿过射线,则该点位于多边形内部。

    在矩形的情况下,零到两条线之间的线将穿过射线。

    如果一条线接触到光线但没有穿过它,则结果是不明确的。因此,在你的计算中,假设光线是一个无限小的量,比它的y坐标高,所以它是 不可能的 让一条线接触光线而不穿过它。

    考虑到测试点(x,y)和线(x1,y1,x2,y2),测试一条线是否穿过射线非常简单。在不丧失一般性的前提下,假设y1<y2。然后

    if y < y2 and y >= y1:
        let x0 = x1 + (y-y1)/(y2-y1) * (x2-x1) // crossing point (x0,y)
        if x0 > x:
            crossing_detected++
    

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

        5
  •  0
  •   Landei    16 年前

    很容易测试一个点是否位于三角形中,所以可以将矩形拆分为两个三角形并测试这些三角形。参见 http://www.blackpawn.com/texts/pointinpoly/default.html

        6
  •  0
  •   bleater    8 年前

    四边形点的一般检验就足够了。四元被定义为一系列有序的点。顺时针和逆时针旋转:

    typedef struct {float x; float y} vec2;
    bool pointIsInQuad(const vec2 point, const vec2 quad[4])
    {
        bool sides[4];
        for (int i = 0; i < 4; i++) {
            sides[i] = ((point.x - quad[i].x)*(quad[(i + 1)%4].y - quad[i].y) - (point.y - quad[i].y)*(quad[(i + 1)%4].x - quad[i].x)) > 0.0f;
        }
        return ((sides[0] == sides[1]) && (sides[0] == sides[2]) && (sides[0] == sides[3]));
    }