如何找到给定点最近的未被圆数组覆盖的点?附游戏场景需求
解决方案步骤
一、先实现核心几何判断工具
所有逻辑依赖两个基础判断函数,优先实现:
1. 判断点是否在已绘制区域内
遍历所有已绘制圆形,通过距离平方判断(避免开根号提升性能):
def is_point_in_drawn_area(p, circles): px, py = p for (cx, cy, r) in circles: distance_sq = (px - cx)**2 + (py - cy)**2 if distance_sq <= r**2: return True return False
2. 判断点是否在指定矩形内
假设矩形由(x_min, y_min)(左下角)和(x_max, y_max)(右上角)定义,可根据游戏坐标系方向调整:
def is_point_in_rect(p, rect_x_min, rect_x_max, rect_y_min, rect_y_max): px, py = p return rect_x_min <= px <= rect_x_max and rect_y_min <= py <= rect_y_max
二、寻找最近的未绘制区域点
推荐两种实用方案,可根据游戏性能需求选择:
方案1:射线扫描法(快速定位)
从角色位置向多方向发射射线,逐步扩大搜索范围,找到第一个符合条件的点:
def find_closest_undrawn_point(player_pos, circles, rect): px, py = player_pos rect_x_min, rect_x_max, rect_y_min, rect_y_max = rect # 定义12个扫描方向,覆盖所有角度 directions = [ (1,0), (-1,0), (0,1), (0,-1), (1,1), (1,-1), (-1,1), (-1,-1), (0.707,0.707), (-0.707,0.707), (0.707,-0.707), (-0.707,-0.707) ] step = 5 # 步长可根据游戏缩放调整 max_dist = max(rect_x_max - rect_x_min, rect_y_max - rect_y_min) for distance in range(step, max_dist + 1, step): for dx, dy in directions: cx = px + dx * distance cy = py + dy * distance candidate = (cx, cy) if is_point_in_rect(candidate, *rect) and not is_point_in_drawn_area(candidate, circles): return candidate # 所有方向都找不到,返回None return None
方案2:边界采样法(精准定位)
遍历所有已绘制圆的边界,生成外部采样点,筛选出符合条件的点后取距角色最近的:
import math def find_precise_closest_undrawn_point(player_pos, circles, rect): px, py = player_pos rect_x_min, rect_x_max, rect_y_min, rect_y_max = rect candidates = [] sample_count = 32 # 每个圆采样点数,越多越精准 for (cx, cy, r) in circles: for i in range(sample_count): angle = 2 * math.pi * i / sample_count # 生成圆外2单位的采样点 x = cx + (r + 2) * math.cos(angle) y = cy + (r + 2) * math.sin(angle) candidate = (x, y) if is_point_in_rect(candidate, *rect) and not is_point_in_drawn_area(candidate, circles): candidates.append(candidate) if not candidates: return None # 按距离角色从近到远排序 candidates.sort(key=lambda p: (p[0]-px)**2 + (p[1]-py)**2) return candidates[0]
三、箭头指向逻辑
拿到目标点后,计算角色到目标点的方向角度,用于旋转箭头:
def get_arrow_rotation(player_pos, target_pos): px, py = player_pos tx, ty = target_pos dx = tx - px dy = ty - py # 计算弧度,若游戏用角度则转成degrees return math.atan2(dy, dx)
四、区域完成判定
当上述寻找函数返回None时,说明矩形内所有区域已被绘制覆盖,直接判定区域“完成”。
内容的提问来源于stack exchange,提问作者hudzell
相关产品推荐
相关产品推荐

