第一个计算几何算法的可视化---极点法获取凸包

  1. 生成随机的点

  2. 使用EP算法得到极点

    • 初始化状态
    • 3重循环遍历三角形
    • 第四重循环判断点
    • intriagle测试里面先要保证三角形的顶点是CCW
    • to-left测试的计算公式
  3. 可视化所有的点

  4. 完整代码

    import pygame
    import random
    
    # 定义颜色
    RED = (255, 0, 0)
    GREEN = (0, 255, 0)
    BACKGROUND_COLOR = (255, 255, 255)
    
    
    class Point:
        def __init__(self, x, y):
            self.x = x
            self.y = y
            self.extreme = True
    
    def toLeft(p, q, s):
        area = p.x * q.y - p.y * q.x + \
               q.x * s.y - q.y * s.x + \
               s.x * p.y - s.y * p.x
    
        return area > 0
    
    
    
    def InTriangle(p, q, r, s):
        # 这里需要一个函数来检测点s是否在由p, q, r形成的三角形内
        # 返回True如果s在三角形内, 否则返回False
        # NOTE: 这个函数的具体实现需要更多的背景知识来完成,这里我暂时用一个简单的返回值代替
        if not toLeft(p, q, r):
            p, r = r, p
    
        ret1 = toLeft(p, q, s)
        ret2 = toLeft(q, r, s)
        ret3 = toLeft(r, p, s)
        if ret1 and ret2 and ret3:
            return True
        return False
    
    def extremePoint(points):
        n = len(points)
        for s in range(n):
            points[s].extreme = True
    
        for p in range(n):
            for q in range(p + 1, n):
                for r in range(q + 1, n):
                    for s in range(n):
                        if s == p or s == q or s == r or not points[s].extreme:
                            continue
                        if InTriangle(points[p], points[q], points[r], points[s]):
                            points[s].extreme = False
                            break
    
    # 生成随机点
    def generate_random_points(num_points=40, xlim=(0, 700), ylim=(0, 500)):
        return [Point(random.randint(xlim[0], xlim[1]), random.randint(ylim[0], ylim[1])) for _ in range(num_points)]
        # return [Point(0, 0), Point(100, 0), Point(50, 100), Point(50, 50)]
    
    
    def visualize(points, width=800, height=600):
        pygame.init()
        screen = pygame.display.set_mode((width, height))
        pygame.display.set_caption('Visualization of Extreme Points')
        font = pygame.font.SysFont(None, 24)  # 使用默认字体,大小为24
    
        running = True
        while running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
    
            screen.fill(BACKGROUND_COLOR)
            index = 0
            for point in points:
                if point.extreme:
                    pygame.draw.circle(screen, GREEN, (point.x, height - point.y), 6)
                else:
                    pygame.draw.circle(screen, RED, (point.x, height - point.y), 3)
    
                label = font.render(str(index), True, (0, 0, 0))  # 使用黑色显示序号
                screen.blit(label, (point.x + 10, height - point.y - 10))
                index += 1
    
            pygame.display.flip()
    
        pygame.quit()
    
    
    # 主程序
    if __name__ == "__main__":
        points = generate_random_points()
        extremePoint(points)
        # for point in points:
        #     if point.extreme:
        #         print(f"极点: ({point.x}, {point.y})")
        visualize(points)
    
    1. 运行结果

      1. 补充一下极边法,其实变化不大,只写一下核心的代码:
python 复制代码
    
      
def extremeEdge(points):
    n = len(points)
    for s in range(n):
        points[s].extreme = False

    for p in range(n):
        for q in range(p + 1, n):
            true_count = 0
            false_count = 0
            for target in range(n):
                if target == p or target == q:
                    continue

                if toLeft(points[p], points[q], points[target]):
                    true_count += 1
                else:
                    false_count += 1

            if true_count * false_count == 0:
                points[p].extreme = True
                points[q].extreme = True
相关推荐
程序猿进阶几秒前
深入解析 Spring WebFlux:原理与应用
java·开发语言·后端·spring·面试·架构·springboot
Python之栈1 分钟前
【无标题】
数据库·python·mysql
qq_433618443 分钟前
shell 编程(二)
开发语言·bash·shell
charlie11451419117 分钟前
C++ STL CookBook
开发语言·c++·stl·c++20
袁袁袁袁满17 分钟前
100天精通Python(爬虫篇)——第113天:‌爬虫基础模块之urllib详细教程大全
开发语言·爬虫·python·网络爬虫·爬虫实战·urllib·urllib模块教程
ELI_He99924 分钟前
PHP中替换某个包或某个类
开发语言·php
m0_7482361131 分钟前
Calcite Web 项目常见问题解决方案
开发语言·前端·rust
倔强的石头10639 分钟前
【C++指南】类和对象(九):内部类
开发语言·c++
老大白菜40 分钟前
Python 爬虫技术指南
python
Watermelo61744 分钟前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript