Tính giao điểm của hai đường tròn?


29

Tôi đang cố gắng tìm ra cách tính toán một cách toán học các điểm chung của hai vòng tròn giao nhau trên bề mặt trái đất với một tâm Lat / Lon và bán kính cho mỗi điểm.

Ví dụ: đã cho:

  • Lat / Lon (37,673442, -90,234036) Bán kính 107,5 NM
  • Lat / Lon (36.109997, -90.953669) Bán kính 145 NM

Tôi nên tìm hai điểm giao nhau với một trong số chúng là (36.948, -088.158).

Sẽ rất dễ dàng để giải quyết điều này trên một mặt phẳng nhưng tôi không có kinh nghiệm giải phương trình trên một mặt cầu không hoàn hảo như bề mặt trái đất.


1
Nếu tất cả các bán kính của bạn sẽ nhỏ như vậy (dưới vài km), thì trái đất về cơ bản là phẳng ở quy mô này và bạn cũng có thể chọn một phép chiếu chính xác, đơn giản và thực hiện các phép tính Euclide thông thường. Hãy chắc chắn rằng bạn tính toán giao điểm đến hơn ba vị trí thập phân - phần không chính xác ở vị trí thập phân thứ ba lớn bằng một trong hai bán kính của bạn!
whuber

1
Tôi nên thêm các đơn vị, bán kính đó tính bằng NM để nó vẫn còn một khoảng cách nhỏ so với bề mặt trái đất nhưng lớn hơn vài km. Làm thế nào để quy mô đó ảnh hưởng đến sự biến dạng? Tôi đang cố gắng tìm một giải pháp chính xác đến dưới <1nm, vì vậy nó không phải là siêu chính xác. Cảm ơn!
Sẽ

Đây là tất cả những điều tốt để biết, bởi vì nó cho thấy bạn có thể sử dụng một mô hình hình cầu của trái đất - các mô hình elip phức tạp hơn là không cần thiết.
whuber

@whuber Điều này có nghĩa là vấn đề có thể được giải quyết như sau: tìm giao điểm của 3 hình cầu trong đó một trong những hình cầu là trái đất và hai phần còn lại tập trung vào các điểm với bán kính tương ứng của chúng?
Kirk Kuykendall

@Kirk Vâng, đó là cách để làm điều đó, giả sử một mô hình hình cầu của bề mặt trái đất. Sau một số tính toán sơ bộ làm giảm điều này thành một trường hợp đặc biệt của vấn đề Trilateration trong 3D. (Các tính toán là cần thiết để chuyển đổi khoảng cách dọc theo vòng cung hình cầu sang khoảng cách dọc theo hợp âm hình cầu, trở thành bán kính của hai quả cầu nhỏ hơn.)
whuber

Câu trả lời:


21

Nó không khó hơn nhiều trên mặt cầu so với trên máy bay, một khi bạn nhận ra rằng

  1. Các điểm trong câu hỏi là các giao điểm lẫn nhau của ba hình cầu: một hình cầu tập trung bên dưới vị trí x1 (trên bề mặt trái đất) của một bán kính nhất định, một hình cầu tập trung bên dưới vị trí x2 (trên bề mặt trái đất) của một bán kính nhất định và chính trái đất , là một hình cầu có tâm ở O = (0,0,0) của bán kính cho trước.

  2. Giao điểm của mỗi trong hai hình cầu đầu tiên với bề mặt trái đất là một hình tròn, xác định hai mặt phẳng. Do đó, các giao điểm lẫn nhau của cả ba mặt cầu đều nằm trên giao điểm của hai mặt phẳng đó: một đường thẳng .

Do đó, vấn đề được giảm xuống để giao một đường thẳng với một hình cầu, rất dễ dàng.


Đây là những thông tin chi tiết. Các đầu vào là các điểm P1 = (lat1, lon1) và P2 = (lat2, lon2) trên bề mặt trái đất, được coi là một hình cầu và hai bán kính r1 và r2 tương ứng.

  1. Chuyển đổi (lat, lon) thành (x, y, z) tọa độ địa tâm. Như thường lệ, vì chúng ta có thể chọn các đơn vị đo lường trong đó trái đất có bán kính đơn vị,

    x = cos(lon) cos(lat)
    y = sin(lon) cos(lat)
    z = sin(lat).
    

    Trong ví dụ, P1 = (-90,234036 Độ, 37,673442 Độ) có tọa độ địa tâm x1 = (-0,00323306, -0,7915, 0,61116) và P2 = (-90,953669 Độ, 36.109997 Độ) có tọa độ địa tâm x2 = (-0,0134 , 0,589337).

  2. Chuyển đổi bán kính r1 và r2 (được đo dọc theo mặt cầu) thành các góc dọc theo mặt cầu. Theo định nghĩa, một hải lý (NM) là 1/60 độ cung (là pi / 180 * 1/60 = 0,0002908888 radian). Do đó, như các góc,

    r1 = 107.5 / 60 Degree = 0.0312705 radian
    r2 = 145 / 60 Degree = 0.0421788 radian
    
  3. Các đo đạc vòng tròn bán kính r1 khoảng x1 là giao điểm của bề mặt trái đất với một Euclide lĩnh vực của tội lỗi bán kính (r1) tập trung ở cos (r1) * x1.

  4. Mặt phẳng được xác định bởi giao điểm của hình cầu bán kính sin (r1) quanh cos (r1) * x1 và bề mặt trái đất vuông góc với x1 và đi qua điểm cos (r1) x1, khi đó phương trình của nó là x.x1 = cos (r1) ("." đại diện cho sản phẩm chấm thông thường ); tương tự cho mặt phẳng khác. Sẽ có một điểm x0 duy nhất trên giao điểm của hai mặt phẳng đó là sự kết hợp tuyến tính của x1 và x2. Viết x0 = a x1 + b * x2 hai phương trình phẳng là

    cos(r1) = x.x1 = (a*x1 + b*x2).x1 = a + b*(x2.x1)
    cos(r2) = x.x2 = (a*x1 + b*x2).x2 = a*(x1.x2) + b
    

    Sử dụng thực tế là x2.x1 = x1.x2, mà tôi sẽ viết là q, giải pháp (nếu nó tồn tại) được đưa ra bởi

    a = (cos(r1) - cos(r2)*q) / (1 - q^2),
    b = (cos(r2) - cos(r1)*q) / (1 - q^2).
    

    Trong ví dụ đang chạy, tôi tính a = 0,973503 và b = 0,0260194.

    Rõ ràng chúng ta cần q ^ 2! = 1. Điều này có nghĩa là x1 và x2 có thể không phải là cùng một điểm cũng không phải là điểm đối cực.

  5. Bây giờ tất cả các điểm khác trên đường giao nhau của hai mặt phẳng khác với x0 bởi một số bội của một vectơ n vuông góc với cả hai mặt phẳng. Các sản phẩm chéo

    n = x1~Cross~x2
    

    không công việc được cung cấp n là khác không: một lần nữa, điều này có nghĩa là x1 và x2 không trùng nhau và ngược chiều nhau. . .

  6. Do đó, chúng tôi tìm kiếm tối đa hai điểm có dạng x0 + t * n nằm trên bề mặt trái đất: nghĩa là chiều dài của chúng bằng 1. Tương đương, độ dài bình phương của chúng là 1:

    1 = squared length = (x0 + t*n).(x0 + t*n) = x0.x0 + 2t*x0.n + t^2*n.n = x0.x0 + t^2*n.n
    

    Thuật ngữ với x0.n biến mất vì x0 (là tổ hợp tuyến tính của x1 và x2) vuông góc với n. Hai giải pháp dễ dàng là

    t = sqrt((1 - x0.x0)/n.n)
    

    và tiêu cực của nó. Một lần nữa độ chính xác cao được gọi là vì khi x1 và x2 gần, x0.x0 rất gần với 1, dẫn đến mất một số độ chính xác của dấu phẩy động. Trong ví dụ, t = 1.07509 hoặc t = -1,07509. Hai điểm giao nhau do đó bằng nhau

    x0 + t*n = (0.0257661, -0.798332, 0.601666)
    x0 - t*n = (-0.0327606, -0.784759, 0.618935)
    
  7. Cuối cùng, chúng tôi có thể chuyển đổi các giải pháp này trở lại (lat, lon) bằng cách chuyển đổi địa tâm (x, y, z) sang tọa độ địa lý:

    lon = ArcTan(x,y)
    lat = ArcTan(Sqrt[x^2+y^2], z)
    

    Đối với kinh độ, sử dụng các giá trị trả về arctangent tổng quát trong phạm vi -180 đến 180 độ (trong các ứng dụng điện toán, hàm này lấy cả x và y làm đối số thay vì chỉ tỷ lệ y / x; đôi khi nó được gọi là "ATan2").

    Tôi nhận được hai giải pháp (-88.151426, 36.989311) và (-92.390485, 38.238380), được hiển thị trong hình dưới dạng các chấm màu vàng.

Hình 3D

Các trục hiển thị tọa độ địa tâm (x, y, z). Các mảng màu xám là một phần của bề mặt trái đất từ ​​-95 đến -87 độ kinh độ, vĩ độ 33 đến 40 độ (được đánh dấu bằng một tấm lưới một độ). Bề mặt trái đất đã được làm trong suốt một phần để hiển thị cả ba hình cầu. Tính chính xác của các giải pháp được tính toán thể hiện rõ qua cách các điểm màu vàng nằm ở giao điểm của các mặt cầu.


Bill, điều này thật tuyệt vời. Một cách làm rõ bạn có thể thêm vào, dựa trên ai đó đang cố gắng thực hiện nó. Ở bước 2, bạn không chuyển đổi rõ ràng từ độ sang radian.
Jersey Andy

@Jersey Cảm ơn bạn đã chỉnh sửa. Tôi đã thay đổi nó một chút để tránh sự dư thừa và để giữ cho các công thức rõ ràng nhất có thể. Đọc xong chủ đề mà bạn đang đề cập, tôi cũng chèn một liên kết để giải thích về sản phẩm chấm.
whuber

8

Các trường hợp ellipsoidal :

Vấn đề này là một khái quát của một trong những tìm kiếm ranh giới hàng hải được định nghĩa là "đường trung tuyến" và có một tài liệu rộng rãi về chủ đề này. Giải pháp của tôi cho vấn đề này là tận dụng phép chiếu phương vị tương đương:

  1. Đoán tại điểm giao
  2. Chiếu hai điểm cơ bản bằng cách sử dụng điểm giao nhau được đoán này làm tâm của phép chiếu phương vị tương đương,
  3. Giải bài toán giao nhau trong không gian chiếu 2d.
  4. Đó là điểm giao cắt mới quá xa điểm cũ, quay lại bước 2.

Thuật toán này hội tụ bậc hai và mang lại một giải pháp chính xác trên một ellipsoid. (Độ chính xác là bắt buộc trong trường hợp ranh giới trên biển, vì nó quyết định quyền đánh bắt, dầu mỏ và khoáng sản.)

Các công thức được đưa ra trong Phần 14 của trắc địa trên một elipsoid của cuộc cách mạng . Phép chiếu phương vị tương đương ellipsoidal được cung cấp bởi GeographicLib . Một phiên bản MATLAB có sẵn tại các phép chiếu Geodesic cho một ellipsoid .


+1 Đó là một bài báo tuyệt vời: mô tả khiêm tốn của bạn ở đây không làm điều đó công bằng.
whuber

Xem thêm bài viết ngắn hơn của tôi về trắc địa "Thuật toán cho trắc địa" dx.doi.org/10.1007/s00190-012-0578-z (tải xuống miễn phí!) Cộng với errata và phụ lục cho các bài viết này geographiclib.sf.net/geod-addenda.html
cffk

1

Đây là một số mã R để làm điều này:

p1 <- cbind(-90.234036, 37.673442) 
p2 <- cbind(-90.953669, 36.109997 )

library(geosphere)
steps <- seq(0, 360, 0.1)
c1 <- destPoint(p1, steps, 107.5 * 1852)
c2 <- destPoint(p2, steps, 145 * 1852)

library(raster)
s1 <- spLines(c1)
s2 <- spLines(c2)

i <- intersect(s1, s2)
coordinates(i)

#        x        y
# -92.38241 38.24267
# -88.15830 36.98740

s <- bind(s1, s2)
crs(s) <- "+proj=longlat +datum=WGS84"
plot(s)
points(i, col='red', pch=20, cex=2)

1

Theo câu trả lời của @ whuber , đây là một số mã Java hữu ích vì hai lý do:

  • nó làm nổi bật một gotcha liên quan đến ArcTan (đối với Java và có thể các ngôn ngữ khác?)
  • nó xử lý các trường hợp cạnh có thể, bao gồm một trường hợp không được đề cập trong câu trả lời của @ whuber.

Nó không được tối ưu hóa hoặc hoàn thành (tôi đã bỏ qua các lớp rõ ràng như Point), nhưng nên thực hiện thủ thuật.

public static List<Point> intersection(EarthSurfaceCircle c1, EarthSurfaceCircle c2) {

    List<Point> intersections = new ArrayList<Point>();

    // project to (x,y,z) with unit radius
    UnitVector x1 = UnitVector.toPlanar(c1.lat, c1.lon);
    UnitVector x2 = UnitVector.toPlanar(c2.lat, c2.lon);

    // convert radii to radians:
    double r1 = c1.radius / RadiusEarth;
    double r2 = c2.radius / RadiusEarth;

    // compute the unique point x0
    double q = UnitVector.dot(x1, x2);
    double q2 = q * q;
    if (q2 == 1) {
        // no solution: circle centers are either the same or antipodal
        return intersections;
    }
    double a = (Math.cos(r1) - q * Math.cos(r2)) / (1 - q2);
    double b = (Math.cos(r2) - q * Math.cos(r1)) / (1 - q2);
    UnitVector x0 = UnitVector.add(UnitVector.scale(x1, a), UnitVector.scale(x2, b));

    // we only have a solution if x0 is within the sphere - if not,
    // the circles are not touching.
    double x02 = UnitVector.dot(x0, x0);
    if (x02 > 1) {
        // no solution: circles not touching
        return intersections;
    }

    // get the normal vector:
    UnitVector n = UnitVector.cross(x1, x2);
    double n2 = UnitVector.dot(n, n);
    if (n2 == 0) {
        // no solution: circle centers are either the same or antipodal
        return intersections;
    }

    // find intersections:
    double t = Math.sqrt((1 - UnitVector.dot(x0, x0)) / n2);
    intersections.add(UnitVector.toPolar(UnitVector.add(x0, UnitVector.scale(n, t))));
    if (t > 0) {
        // there's only multiple solutions if t > 0
        intersections.add(UnitVector.toPolar(UnitVector.add(x0, UnitVector.scale(n, -t))));
    }
    return intersections;
}

Ngoài ra, quan trọng, lưu ý việc sử dụng atan2- đó là mặt trái của những gì bạn mong đợi từ câu trả lời của @ whuber (Tôi không biết tại sao, nhưng nó hoạt động):

    public static Point toPolar(UnitVector a) {
        return new Point(
                Math.toDegrees(Math.atan2(a.z, Math.sqrt(a.x * a.x + a.y * a.y))),
                Math.toDegrees(Math.atan2(a.y, a.x)));          
    }

0

Mã 'R' hoạt động cho câu trả lời @wuhber.

P1 <- c(37.673442, -90.234036)
P2 <- c(36.109997, -90.953669) 

#1 NM nautical-mile is 1852 meters
R1 <- 107.5
R2 <- 145

x1 <- c(
  cos(deg2rad(P1[2])) * cos(deg2rad(P1[1])),  
  sin(deg2rad(P1[2])) * cos(deg2rad(P1[1])),
  sin(deg2rad(P1[1]))
);

x2 <- c(
  cos(deg2rad(P2[2])) * cos(deg2rad(P2[1])),
  sin(deg2rad(P2[2])) * cos(deg2rad(P2[1])),
  sin(deg2rad(P2[1]))
);

r1 = R1 * (pi/180) * (1/60)
r2 = R2 * (pi/180) * (1/60)

q = dot(x1,x2)
a = (cos(r1) - cos(r2) * q) / (1 - q^2)
b = (cos(r2) - cos(r1) * q)/ (1 - q^2)

n <- cross(x1,x2)

x0 = a*x1 + b*x2


t = sqrt((1 - dot(x0, x0))/dot(n,n))

point1 = x0 + (t * n)
point2 = x0 - (t * n)

lat1 = rad2deg(atan2(point1[2] ,point1[1]))
lon1= rad2deg(asin(point1[3]))
paste(lat1, lon1, sep=",")

lat2 = rad2deg(atan2(point2[2] ,point2[1]))
lon2 = rad2deg(asin(point2[3]))
paste(lat2, lon2, sep=",")

-1

Nếu một trong các vòng tròn là Nortstar, thì có một cách dễ nhất với khối cầu đơn vị.

Bạn có thể đo vĩ độ của bạn với Nortstar. Sau đó, bạn có một vị trí tương đối trên quả cầu này. v1 (0, sin (la), cos (la)) Bạn biết vị trí (góc) của một ngôi sao khác (star2), từ almanach. v2 (sin (lo2) * cos (la2), sin (la2), cos (lo2) * cos (la2)) Các vectơ của nó. Từ phương trình của mặt cầu.

lo2 là kinh độ tương đối. Nó unknow .

Góc giữa bạn và star2, bạn cũng có thể đo, (m) Và bạn biết đấy, sản phẩm bên trong của hai vectơ đơn vị là cos (góc) ở giữa. cos (m) = dot (v1, v2) u có thể tính toán kinh độ tương đối (lo2). lo2 = acos ((cos (m) -sin (la) * sin (la2)) / (cos (la) * cos (la2)))

Sau tất cả, bạn thêm kinh độ thực của star2 vào lo2. (hoặc phụ, phụ thuộc vào phía tây từ bạn hoặc phía đông.) lo2 bây giờ là kinh độ của bạn.

Xin lỗi vì tiếng Anh của tôi, tôi không bao giờ học ngôn ngữ này.


2 điều: Northstar có nghĩa là sao cực.

Khác. Bởi vì góc đo theo chiều ngang tương đối, luôn cần hiệu chỉnh 90 góc. Nó hợp lệ với góc m quá.

ps: góc thực có nghĩa là: vị trí sao - hiệu chỉnh thời gian.


Không rõ làm thế nào điều này trả lời câu hỏi.
whuber
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.