python判断点在四边形内

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

只针对凸四边形:

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

import glob

class Point():
    def __init__(self, x,y):
         self.x=x
         self.y=y


def GetCross(p1, p2, p):
    return (p2.x - p1.x) * (p.y - p1.y) - (p.x - p1.x) * (p2.y - p1.y)

def IsPointInMatrix(p1, p2, p3, p4, p):
    isPointIn = GetCross(p1, p2, p) * GetCross(p3, p4, p) >= 0 and GetCross(p2, p3, p) * GetCross(p4, p1, p) >= 0
    return isPointIn

if __name__ == '__main__':

     p1=Point(1,1)
     p2=Point(3,1)
     p3=Point(4,4)
     p4=Point(1,3)

     pp=Point(2,2)
     pp2=Point(4,2)

     print(IsPointInMatrix(p1,p2,p3,p4,pp))
     print(IsPointInMatrix(p1,p2,p3,p4,pp2))

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

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

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# @Time    : 2018-04-13  15:58
# @Author  : PengZhw
# @Software: PyCharm

import math  # 要用到平方根函数,导入数学库

# 先写一个函数来计算一个点(A)朝向一线段(BC)的张角,待会在下一个函数中会调用
def angle(ax, ay, bx, by, cx, cy):  # 接收三个点的坐标
    # ↑angle()函数用余弦定理来计算一个点对其他两个点的张角
    a = math.sqrt((bx - cx) ** 2 + (by - cy) ** 2)
    # ↑余弦定理需要三边长,如图,这是△ABC中和点A相对的那条边BC的长度a
    b = math.sqrt((cx - ax) ** 2 + (cy - ay) ** 2)
    # ↑这是△ABC中和点B相对的那条边AC的长度b,math.sqrt(x)是x的平方根
    c = math.sqrt((bx - ax) ** 2 + (by - ay) ** 2)
    # ↑这是△ABC中和点C相对的那条边AB的长度c
    alpha = math.acos((b ** 2 + c ** 2 - a ** 2) / (2 * b * c))
    # ↑余弦定理公式求出角α
    return alpha  # 返回α,α是一个弧度制的值

def if_cover(a_x, a_y, b_x, b_y, c_x, c_y, d_x, d_y, e_x, e_y):
    # ↑接收五个点,其中各个点的名字对应图上的各点
    # if_cover()函数用余弦定理判断给定点A点是否在凸四边形BCDE内

    """
    β(beta)是点A对四边形四条边的张角,如果四个张角和为360°则显然A在四边形BCDE之内,
    如果张角和不为360°则A在四边形BCDE之外。

    """
    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) + \
           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)
    # ↑↑↑一句话太长了需要转行才能说完,便于阅读

    """
    round(x, a)的含义是对x保留a位小数,如round(beta, 5)就是对beta保留5位小数
    """
    if round(beta, 5) == round(math.pi * 2, 5):  # 如果β等于2π
        print(round(beta, 5), round(math.pi * 2, 5))
        print("点(%d, %d)在四边形[(%d, %d), (%d, %d), (%d, %d), (%d, %d)]内。" % (
            a_x, a_y, b_x, b_y, c_x, c_y, d_x, d_y, e_x, e_y))
        return True  # 则返回True
    else:
        print(round(beta, 5), round(math.pi * 2, 5))
        print("点[%f, %f]不在四边形内。" % (a_x, a_y))
        return False  # 否则返回False

# 举例
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写的

local pos1 = cc.p(200, 200)
local pos2 = cc.p(500, 200)
local pos3 = cc.p(450, 500)
local pos4 = cc.p(150, 500)
local minx = math.min(pos1.x, pos2.x, pos3.x, pos4.x)
local maxx = math.max(pos1.x, pos2.x, pos3.x, pos4.x)
local miny = math.min(pos1.y, pos2.y, pos3.y, pos4.y)
local maxy = math.max(pos1.y, pos2.y, pos3.y, pos4.y)
local function GetCross(p1, p2, p)
    return (p2.x - p1.x) * (p.y - p1.y) - (p.x - p1.x) * (p2.y - p1.y);
end
-- // 计算 |p1 p2| X |p1 p|
-- function GetCross(p1: Point, p2: Point, p: Point) {
--     return (p2.x - p1.x) * (p.y - p1.y) - (p.x - p1.x) * (p2.y - p1.y);
-- }
-- //判断点p是否在p1p2p3p4的四方形内
function IsPointInMatrix(p1, p2, p3, p4, p)
    local isPointIn = GetCross(p1, p2, p) * GetCross(p3, p4, p) >= 0 and GetCross(p2, p3, p) * GetCross(p4, p1, p) >= 0;
    return isPointIn;
end
function randPoint( ... )

    --确定下X值
    local x = math.random(minx, maxx)
    -- local x = 181
    -- 计算下四条线上, 当前X值的有效范围
    -- 线的公式是 f(x) = x + n  
    local getY1 = function(p1, p2, num)
        local max = math.max(p1.x, p2.x)
        local min = math.min(p1.x, p2.x)
        if num < min or num > max then
            -- print("超出范围 getY1", num, max, num)
            return -1
        end
        if max == min then
            if num == max then
                return p1.y
            else
                return -1
            end
        end

        local n1 = (p2.y - p1.y)/(p2.x - p1.x)

        print("n1", n1, p2.y, p1.y, p2.x, p1.x)
        local numy = (num - p1.x) * n1 + p1.y

        return numy
    end 

    local y1 = getY1(pos1, pos2, x)
    local y2 = getY1(pos2, pos3, x)
    local y3 = getY1(pos3, pos4, x)
    local y4 = getY1(pos4, pos1, x)
    print("获取的第一个值是Y", x, y1, y2, y3, y4)
    local point = {}
    if y1 ~= -1 then
        table.insert(point, y1)
    end    
    if y2 ~= -1 then
        table.insert(point, y2)
    end    
    if y3 ~= -1 then
        table.insert(point, y3)
    end    
    if y4 ~= -1 then
        table.insert(point, y4)
    end

    local y = math.random(point[1], point[2])
    print("最终值", x, y, point[1], point[2])
    --检测是否在矩形内
    local inPoint = IsPointInMatrix(pos1,pos2,pos3,pos4, cc.p(x, y))
    if not inPoint then
         
    else

    end
end

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

相关文章