-
生成随机的点
-
使用EP算法得到极点
- 初始化状态
- 3重循环遍历三角形
- 第四重循环判断点
- intriagle测试里面先要保证三角形的顶点是CCW
- to-left测试的计算公式
-
可视化所有的点
-
完整代码
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)
-
运行结果
- 补充一下极边法,其实变化不大,只写一下核心的代码:
-
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