python判断点在四边形内

x33g5p2x  于2021-11-10 转载在 Python  
字(3.9k)|赞(0)|评价(0)|浏览(504)

只针对凸四边形:

如果是三角形,五边形呢?这个代码是否有效,还没测

  1. import glob
  2. class Point():
  3. def __init__(self, x,y):
  4. self.x=x
  5. self.y=y
  6. def GetCross(p1, p2, p):
  7. return (p2.x - p1.x) * (p.y - p1.y) - (p.x - p1.x) * (p2.y - p1.y)
  8. def IsPointInMatrix(p1, p2, p3, p4, p):
  9. isPointIn = GetCross(p1, p2, p) * GetCross(p3, p4, p) >= 0 and GetCross(p2, p3, p) * GetCross(p4, p1, p) >= 0
  10. return isPointIn
  11. if __name__ == '__main__':
  12. p1=Point(1,1)
  13. p2=Point(3,1)
  14. p3=Point(4,4)
  15. p4=Point(1,3)
  16. pp=Point(2,2)
  17. pp2=Point(4,2)
  18. print(IsPointInMatrix(p1,p2,p3,p4,pp))
  19. print(IsPointInMatrix(p1,p2,p3,p4,pp2))

余弦判断点在多边形内,转自:

用余弦定理判断点是否在凸多边形内部 - 知乎

  1. #!/usr/bin/env python3
  2. # -*- coding:utf-8 -*-
  3. # @Time : 2018-04-13 15:58
  4. # @Author : PengZhw
  5. # @Software: PyCharm
  6. import math # 要用到平方根函数,导入数学库
  7. # 先写一个函数来计算一个点(A)朝向一线段(BC)的张角,待会在下一个函数中会调用
  8. def angle(ax, ay, bx, by, cx, cy): # 接收三个点的坐标
  9. # ↑angle()函数用余弦定理来计算一个点对其他两个点的张角
  10. a = math.sqrt((bx - cx) ** 2 + (by - cy) ** 2)
  11. # ↑余弦定理需要三边长,如图,这是△ABC中和点A相对的那条边BC的长度a
  12. b = math.sqrt((cx - ax) ** 2 + (cy - ay) ** 2)
  13. # ↑这是△ABC中和点B相对的那条边AC的长度b,math.sqrt(x)是x的平方根
  14. c = math.sqrt((bx - ax) ** 2 + (by - ay) ** 2)
  15. # ↑这是△ABC中和点C相对的那条边AB的长度c
  16. alpha = math.acos((b ** 2 + c ** 2 - a ** 2) / (2 * b * c))
  17. # ↑余弦定理公式求出角α
  18. return alpha # 返回α,α是一个弧度制的值
  19. def if_cover(a_x, a_y, b_x, b_y, c_x, c_y, d_x, d_y, e_x, e_y):
  20. # ↑接收五个点,其中各个点的名字对应图上的各点
  21. # if_cover()函数用余弦定理判断给定点A点是否在凸四边形BCDE内
  22. """
  23. β(beta)是点A对四边形四条边的张角,如果四个张角和为360°则显然A在四边形BCDE之内,
  24. 如果张角和不为360°则A在四边形BCDE之外。
  25. """
  26. beta = angle(a_x, a_y, b_x, b_y, c_x, c_y) + angle(a_x, a_y, c_x, c_y, d_x, d_y) + \
  27. angle(a_x, a_y, d_x, d_y, e_x, e_y) + angle(a_x, a_y, e_x, e_y, b_x, b_y)
  28. # ↑↑↑一句话太长了需要转行才能说完,便于阅读
  29. """
  30. round(x, a)的含义是对x保留a位小数,如round(beta, 5)就是对beta保留5位小数
  31. """
  32. if round(beta, 5) == round(math.pi * 2, 5): # 如果β等于2π
  33. print(round(beta, 5), round(math.pi * 2, 5))
  34. print("点(%d, %d)在四边形[(%d, %d), (%d, %d), (%d, %d), (%d, %d)]内。" % (
  35. a_x, a_y, b_x, b_y, c_x, c_y, d_x, d_y, e_x, e_y))
  36. return True # 则返回True
  37. else:
  38. print(round(beta, 5), round(math.pi * 2, 5))
  39. print("点[%f, %f]不在四边形内。" % (a_x, a_y))
  40. return False # 否则返回False
  41. # 举例
  42. if_cover(2, 2, 0, 3, 3, 4, 5, 0, 0, 0)

以下内容转自:

在不规则四边形的内部随机一个点_挨踢码农的博客-CSDN博客

** 给定 四边形,在内部随机一个点:**

此问题只针对【凸多边形】
这个问题很有趣,上面一个问题是给定一个点,判断是否在四边形内, 这个问题正好是返过来
思路1, 随机一个位置, 判断是否在四边形内。不是的话就重新随机
答:这个方法好low
于是就有了思路2
思路2,取四个点的minX, maxX, 然后根据X, 求出这个X值在四条边上的点的位置(有可能相交, 有可能不相交,不相交的话就不考虑进去)

如图

这个时候再随机A和B之间就得到了Y值,和之前取出的X值就构成了一个点。 完成。 上代码
代码是lua写的

  1. local pos1 = cc.p(200, 200)
  2. local pos2 = cc.p(500, 200)
  3. local pos3 = cc.p(450, 500)
  4. local pos4 = cc.p(150, 500)
  5. local minx = math.min(pos1.x, pos2.x, pos3.x, pos4.x)
  6. local maxx = math.max(pos1.x, pos2.x, pos3.x, pos4.x)
  7. local miny = math.min(pos1.y, pos2.y, pos3.y, pos4.y)
  8. local maxy = math.max(pos1.y, pos2.y, pos3.y, pos4.y)
  9. local function GetCross(p1, p2, p)
  10.     return (p2.x - p1.x) * (p.y - p1.y) - (p.x - p1.x) * (p2.y - p1.y);
  11. end
  12. -- // 计算 |p1 p2| X |p1 p|
  13. -- function GetCross(p1: Point, p2: Point, p: Point) {
  14. --     return (p2.x - p1.x) * (p.y - p1.y) - (p.x - p1.x) * (p2.y - p1.y);
  15. -- }
  16. -- //判断点p是否在p1p2p3p4的四方形内
  17. function IsPointInMatrix(p1, p2, p3, p4, p)
  18.     local isPointIn = GetCross(p1, p2, p) * GetCross(p3, p4, p) >= 0 and GetCross(p2, p3, p) * GetCross(p4, p1, p) >= 0;
  19.     return isPointIn;
  20. end
  21. function randPoint( ... )
  22.     --确定下X
  23.     local x = math.random(minx, maxx)
  24.     -- local x = 181
  25.     -- 计算下四条线上, 当前X值的有效范围
  26.     -- 线的公式是 f(x) = x + n  
  27.     local getY1 = function(p1, p2, num)
  28.         local max = math.max(p1.x, p2.x)
  29.         local min = math.min(p1.x, p2.x)
  30.         if num < min or num > max then
  31.             -- print("超出范围 getY1", num, max, num)
  32.             return -1
  33.         end
  34.         if max == min then
  35.             if num == max then
  36.                 return p1.y
  37.             else
  38.                 return -1
  39.             end
  40.         end
  41.         local n1 = (p2.y - p1.y)/(p2.x - p1.x)
  42.         print("n1", n1, p2.y, p1.y, p2.x, p1.x)
  43.         local numy = (num - p1.x) * n1 + p1.y
  44.         return numy
  45.     end 
  46.     local y1 = getY1(pos1, pos2, x)
  47.     local y2 = getY1(pos2, pos3, x)
  48.     local y3 = getY1(pos3, pos4, x)
  49.     local y4 = getY1(pos4, pos1, x)
  50.     print("获取的第一个值是Y", x, y1, y2, y3, y4)
  51.     local point = {}
  52.     if y1 ~= -1 then
  53.         table.insert(point, y1)
  54.     end    
  55.     if y2 ~= -1 then
  56.         table.insert(point, y2)
  57.     end    
  58.     if y3 ~= -1 then
  59.         table.insert(point, y3)
  60.     end    
  61.     if y4 ~= -1 then
  62.         table.insert(point, y4)
  63.     end
  64.     local y = math.random(point[1], point[2])
  65.     print("最终值", x, y, point[1], point[2])
  66.     --检测是否在矩形内
  67.     local inPoint = IsPointInMatrix(pos1,pos2,pos3,pos4, cc.p(x, y))
  68.     if not inPoint then
  69.          
  70.     else
  71.     end
  72. end

好没有技术含量呀, 怪我太菜,后面写有技术难度的算法
算法适用凸多边形
————————————————
版权声明:本文为CSDN博主「挨踢码农」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_33039615/article/details/103427907

相关文章