C语言,七巧板,已知七个图形的各点坐标,如何获得七巧板拼成的图案的各个顶点(逆时针顺序)

已有数据或方法:
七个图形各点坐标
判断所给点在哪个图形内部
判断所给点在哪个图形边缘
不考虑重叠,考虑凹多边形

该回答引用ChatGPT4与博主@晓码自在合作编写:

七巧板各顶点坐标的思路:

  1. 定义七个图形的点坐标,例如:
c
int shape1[4][2] = {{1,1},{3,1},{3,3},{1,3}};  // 图1四个点坐标
...
int shape7[6][2] = ...  // 图7六个点坐标

  1. 定义一个数组保存七巧板的所有顶点,初始时为空:
c
int vertices[20][2];  // 七巧板最多20个顶点
int vertexCount = 0;  // 当前顶点个数

  1. 遍历七个图形,对每个图形:

3.1 查找该图形的左上最顶点,添加到vertices数组,vertexCount加1;

3.2 顺时针遍历该图形的所有边,查找与当前边相交的另一个图形的边。

3.3 在相交的两个边中,选择里侧的顶点,添加到vertices数组,vertexCount加1。

3.4 重复3.2和3.3,直到回到起始顶点,遍历完该图形所有边。

  1. vertices数组保存了七巧板的所有顶点坐标(逆时针顺序)。vertexCount为顶点总数。

  2. 可通过vertices数组绘制出七巧板的图形。

该思路的关键在于:顺时针遍历每个图形的边,找到与之相交的另一条边,选择里侧顶点,逐步拼出七巧板的形状。

需要考虑的细节有:

  1. 如何判定两个边相交及选择里侧顶点?(向量与叉积可解决)
  2. 如何处理凹多边形的情况?(保证顺时针遍历)
  3. 重叠的情况?(实际很少,可忽略)

仅供参考(尽管是python):

def PtInPolygons(pt, polygons):  #返回0内|1边|2点|3for p in polygons:
        r=PtInPolygon(pt,p[0])
        if r!=3: return r
    return 3

def PtInPolygon(pt, nodes):  #返回0内|1边|2点|3if len(nodes)<=2: return 3;
    # 判断是否在外包矩形内,如果不在,直接返回3
    Xlist = []
    Ylist = []
    for i in range(len(nodes)-1):
        Xlist.append(nodes[i][0])
        Ylist.append(nodes[i][1])
#   print(Xlist, Ylist)
    maxX = max(Xlist)
    minX = min(Xlist)
    maxY = max(Ylist)
    minY = min(Ylist)
#   print(maxX, minX, maxY, minY)
    if (pt[0] > maxX or pt[0] < minX or pt[1] > maxY or pt[1] < minY):
        return 3
    cnt = 0
    pt1 = nodes[0]
    for i in range(1, len(nodes)):
        pt2 = nodes[i]
        # 点与多边形顶点重合
        if (pt[0] == pt1[0] and pt[1] == pt1[1]) or (pt[0] == pt2[0] and pt[1] == pt2[1]):
#           print("在顶点上")
            return 2
        # 判断线段两端点是否在射线两侧,不在肯定不相交,射线(-∞,Y)(X,Y)
        if (pt1[1] < pt[1] and pt2[1] >= pt[1]) or (pt1[1] >= pt[1] and pt2[1] < pt[1]):
            # 求线段与射线交点 再和Y比较
            pt12X = pt2[0] - (pt2[1] - pt[1]) * (pt2[0] - pt1[0])/(pt2[1] - pt1[1])
#           print(pt12X)
            # 点在多边形边上
            if (pt12X == pt[0]):
#               print("点在多边形边上")
                return 1
            if (pt12X < pt[0]):
                cnt +=1
        pt1 = pt2
#   print(cnt)
    if cnt%2 == 0:
        return 3
    else:
        return 0


  1. 定义七个图形的点坐标,存储在数组中,如points[7][]。
  2. 定义一个结果数组res[]存储图案顶点,初始为空。
  3. 选择一个起点,可以选择points[0][0],将其加入res[]。
  4. 找到含有起点的图形,设为current_shape。
  5. 在current_shape的点集中,找与起点连线的下一个点,设为next_point。
  6. 如果next_point在res[]中,表明此路径已走过,需改道。通过判断next_point在哪个图形的边缘来改道。
  7. 如果next_point不在res[]中,加入res[],并继续在current_shape中找下一个点。
  8. 重复步骤6和7,直到再次遇到起点,完成一个图形的遍历。
  9. 重复步骤4到8,遍历完所有图形,最终res[]中存储的所有点即为图案顶点。10. 根据res[]打印出图案顶点,顺序为逆时针。
    这个思路的关键在于判断一个点在哪个图形内和边缘,来选择正确的路径。如果您已经实现了这两个判断函数,那么获得图案顶点的算法就比较清晰了。需要注意的地方是要考虑凹多边形的情况,确保所有的图形都被遍历到,并且顶点顺序正确。