从Minecraft建筑坐标CSV文件中查找最接近的坐标对
问题描述
我有一份来自Minecraft城市服务器的建筑位置CSV文件,里面包含x和z坐标。我想输入一组附近坐标(防止忘记建筑位置)时,扫描这个CSV文件找到和输入值最接近的坐标对。我感觉自己把问题想复杂了,一直没解决,我知道得把x和z坐标配对后和输入值比较,但不知道具体怎么实现。我试过谷歌搜索自己摸索,目前写了这段代码:
def FindClosest(x,z): with open('buildings.csv', newline='') as f: for row in csv.reader(f): xs = [] zs = [] xs.append(row[3]) zs.append(row[4]) closet_x = closest(xs, x) closet_z = closest(zs, z)
解决方案
你现在的核心问题是没把x和z作为配对的整体计算距离,而是分开找最接近的x和z,这样得到的坐标对大概率不属于同一个建筑,完全不符合需求。
下面是修正后的实现思路和代码:
- 用欧几里得距离判断接近度:平面上两个点(x1,z1)和(x2,z2)的距离可以用平方和
(x1-x2)² + (z1-z2)²来比较(不用开根号,结果大小关系不变,还能节省计算资源)。 - 逐行处理CSV数据:把每行的x、z字符串转成数值类型(直接用字符串比较会出错),计算当前点和输入点的距离平方。
- 跟踪最小距离的坐标:全程记录距离最小的那组坐标,遍历结束后返回结果。
完整代码示例:
import csv def find_closest(target_x, target_z): closest_dist_sq = float('inf') closest_point = None # 确保输入是数值类型 target_x = float(target_x) target_z = float(target_z) with open('buildings.csv', newline='') as f: reader = csv.reader(f) # 如果CSV有表头,取消下面这行的注释跳过表头 # next(reader) for row in reader: # 从第4、5列读取坐标(索引从0开始,row[3]对应第4列) try: build_x = float(row[3]) build_z = float(row[4]) except ValueError: # 跳过格式错误的行 continue # 计算距离平方 dist_sq = (build_x - target_x)**2 + (build_z - target_z)**2 # 更新最近点 if dist_sq < closest_dist_sq: closest_dist_sq = dist_sq # 可以把整行数据都存下来,比如建筑名称等额外信息 closest_point = (build_x, build_z, row) return closest_point # 使用示例 result = find_closest(150, 300) if result: print(f"最近的建筑坐标:x={result[0]}, z={result[1]}") print(f"建筑详情:{result[2]}") else: print("未找到有效建筑坐标")
关键修正说明
- 把x和z作为配对的点计算距离,避免出现“东拼西凑”的无效坐标对
- 将CSV中的字符串坐标转为
float类型,保证数值计算的正确性 - 用
float('inf')初始化最小距离,确保第一个有效点会被选中 - 增加异常处理,跳过CSV中格式错误的行
- 如果你的CSV有表头,记得启用
next(reader)跳过第一行内容
内容的提问来源于stack exchange,提问作者Salad Hat
相关产品推荐
相关产品推荐

