根据距离指定点的二维坐标

根据相互距离指定n个点的二维坐标。

方案

1. 首先指定前3个点的坐标(根据2个圆)

  • 设置常量AxAy作为A点坐标
  • AB的距离为Dab,则B点坐标设置为Bx = Ax - Dab, By = Ay
  • CA的距离为Dac作为第1个圆的半径R1CB的距离为Dbc作为第2个圆的半径R2
  • A点为圆心,R1为半径画圆1,以B点为圆心,R2为半径画圆2
  • 两个交点任选一个作为C点坐标

2. 然后指定剩余n-3个点的坐标(根据3个圆)

  • 利用A、B和C三个点依次确定剩余点的坐标
  • 对于剩余点中的某一个点P
    • PA的距离为Dap作为第1个圆的半径R1PB的距离为Dbp作为第2个圆的半径R2
    • A点为圆心,R1为半径画圆1,以B点为圆心,R2为半径画圆2
    • 得到两个交点,根据PC的距离确定P点坐标
  • 完成

实现

1
# 已知n个点两两之间的距离,指定他们的坐标,相互距离保持不变
2
import math
3
import numpy as np
4
5
6
# 用欧式距离计算样本集的距离矩阵
7
# 参数:样本集x,类型为np.array
8
def get_distance(x):
9
    size = len(x)
10
    distance = np.zeros(shape=(len(x), len(x)))
11
    for i in range(0, size - 1):
12
        for j in range(i + 1, size):
13
            distance[i][j] = np.sqrt(np.sum(np.power(x[i] - x[j], 2)))
14
            distance[j][i] = distance[i][j]
15
    return distance
16
17
18
# 计算2个圆的交点
19
def circle_2(p1, r1, p2, r2):
20
    x = p1[0]
21
    y = p1[1]
22
    R = r1
23
    a = p2[0]
24
    b = p2[1]
25
    S = r2
26
    d = math.sqrt((abs(a - x)) ** 2 + (abs(b - y)) ** 2)
27
    if d > (R + S) or d < (abs(R - S)):
28
        print("Two circles have no intersection!")
29
        return
30
    elif d == 0 and R == S:
31
        print("Two circles have same center!")
32
        return
33
    else:
34
        A = (R ** 2 - S ** 2 + d ** 2) / (2 * d)
35
        h = math.sqrt(R ** 2 - A ** 2)
36
        x2 = x + A * (a - x) / d
37
        y2 = y + A * (b - y) / d
38
        x3 = round(x2 - h * (b - y) / d, 2)
39
        y3 = round(y2 + h * (a - x) / d, 2)
40
        x4 = round(x2 + h * (b - y) / d, 2)
41
        y4 = round(y2 - h * (a - x) / d, 2)
42
        c1 = np.array([x3, y3])  # 第1个交点
43
        c2 = np.array([x4, y4])  # 第2个交点
44
        return c1, c2
45
46
47
# 计算3个圆的交点
48
def circle_3(p1, r1, p2, r2, p3, r3):
49
    c1, c2 = circle_2(p1, r1, p2, r2)  # 前2个交点
50
    # 从c1和c2中选择正确的一个
51
    d1 = np.sqrt(np.power(c1[0] - p3[0], 2) + np.power(c1[1] - p3[1], 2))
52
    d2 = np.sqrt(np.power(c2[0] - p3[0], 2) + np.power(c2[1] - p3[1], 2))
53
    if d1 == r3:
54
        return c1
55
    elif d2 == r3:
56
        return c2
57
58
59
# 指定坐标
60
def set_coordinate(dist):
61
    # 先固定前三个点
62
    x = [5]  # 第1个点的x坐标
63
    y = [5]  # 第1个点的y坐标
64
    x.append(5-dist[0][1])  # 第2个点的x坐标
65
    y.append(5)  # 第2个点的y坐标
66
    a = np.array([x[0], y[0]])  # a点坐标
67
    b = np.array([x[1], y[1]])  # b点坐标
68
    r1 = dist[0][2]  # a、c点距离
69
    r2 = dist[1][2]  # b、c点距离
70
    C = circle_2(a, r1, b, r2)  # c点坐标
71
    c = C[0]
72
    x.append(c[0])
73
    y.append(c[1])
74
    # 现在前三个点a,b,c坐标已知,现在指定剩余的n-3个点
75
    for i in range(3, len(dist)):
76
        Ra = dist[0][i]
77
        Rb = dist[1][i]
78
        Rc = dist[2][i]
79
        c = np.array(c)
80
        P = circle_3(a, Ra, b, Rb, c, Rc)
81
        new_x = P[0]
82
        new_y = P[1]
83
        x.append(new_x)
84
        y.append(new_y)
85
    return x, y
86
87
88
if __name__ == '__main__':
89
    x = [[1, 1], [2, 1], [2, 2], [3, 3], [4, 2], [4, 6], [2, 7]]
90
    dist = get_distance(np.array(x))
91
    X, Y = set_coordinate(dist)
92
    xx = []
93
    for i in range(0, len(X)):
94
        xx.append([X[i], Y[i]])
95
    print(xx)  # 指定后n个点的二维坐标列表,形式同x