İki Çemberin Kesişimini Hesaplamak?


29

Her bir nokta için bir merkez Lat / Lon ve bir yarıçap verilen, dünya yüzeyinde kesişen iki dairenin ortak noktalarının matematiksel olarak nasıl türetileceğini çözmeye çalışıyorum.

Örneğin, verilen:

  • Lat / Lon (37.673442, -90.234036) Yarıçapı 107.5 NM
  • Lat / Lon (36.109997, -90.953669) Yarıçapı 145 NM

Biri olmak üzere iki kavşak noktası bulmalıyım (36.948, -088.158).

Bunu düz bir düzlemde çözmek çok kolay olurdu, ancak yeryüzünün yüzeyi gibi kusurlu bir kürede denklem çözme deneyimim yok.


1
Tüm yarıçapınız bu küçük olacaksa (birkaç kilometreden az), o zaman dünya bu ölçekte temelde düzdür ve doğru, basit bir izdüşüm seçip normal Öklid hesaplamalarını yapabilirsiniz. Kesişimi üçten fazla ondalık basamağa kadar hesapladığınızdan emin olun - üçüncü ondalık basamağın içindeki yanlışlık yarıçapınız kadar büyük!
whuber

1
Birimler eklemeliydim, bu yarıçaplar NM'dir, bu yüzden hala dünyanın yüzeyine göre küçük bir mesafe ancak birkaç km'den daha büyük. Bu ölçek bozulmayı nasıl etkiler? <1nm'den daha az doğru bir çözüm bulmaya çalışıyorum, bu yüzden süper kesin olması gerekmiyor. Teşekkürler!
Will

Bunların hepsini bilmek iyi çünkü dünyanın küresel bir modelini kullanabileceğinizi gösteriyor - daha karmaşık elipsoidal modeller gereksiz.
whuber

@whuber Bu, problemin şu şekilde tekrarlanabileceği anlamına mı geliyor: kürelerden birinin dünya olduğu 3 kürenin kesişimini bulmak , diğer ikisi ise kendi yarıçaplarıyla noktalara merkezlenmiş mi?
Kirk Kuykendall

@Kirk Evet, bu, dünya yüzeyinin küresel bir modelini farz ederek böyle yapmanın yolu. Bunu, 3D'deki Trilateration probleminin özel bir durumuna indirgeyen bazı ön hesaplamalardan sonra. (Hesaplamalar, küresel yaylar arasındaki mesafeyi, iki küçük kürenin yarıçapı haline gelen küresel akorlar arasındaki mesafelere dönüştürmek için gereklidir.)
whuber

Yanıtlar:


21

Küre üzerinde, uçakta olduğundan daha zor değil.

  1. Söz konusu noktalar, üç kürenin karşılıklı kesişimidir : verilen bir yarıçapın x1 konumunun altında (dünyanın yüzeyinde) ortalanmış bir küre, belirli bir yarıçapın x2 merkezinin (dünya yüzeyinin altında) ortalanmış bir küre ve dünyanın kendisi bu, belirli bir yarıçapın O = (0,0,0) merkezinde bulunan bir küredir.

  2. İlk iki kürenin her birinin dünya yüzeyiyle kesişmesi, iki düzlemi tanımlayan bir dairedir. Bu nedenle, her üç kürenin karşılıklı kesişme noktaları, bu iki düzlemin kesişme noktasında yatmaktadır: bir çizgi .

Sonuç olarak, sorun, bir çizginin bir küreyle kesişmesiyle azalır, ki bu kolaydır.


İşte detaylar. Girişler, bir küre olarak kabul edilen, dünya yüzeyinde P1 = (lat1, l1) ve P2 = (lat2, l2), ve karşılık gelen iki yarıçapı rl ve r2'dir.

  1. (Lat, lon) (x, y, z) jeosantrik koordinatlarına dönüştürün. Her zamanki gibi, çünkü dünyanın birim yarıçapa sahip olduğu ölçü birimlerini seçebiliriz,

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

    Örnekte, P1 = (-90.234036 Derecesi, 37.673442 Derecesi), x1 = (-0.00323306, -0.7915, 0.61116) Jentrik koordinatlarına ve P2 = (-90.953669 Derecesi, 36.109997 Derecesi), x = = (-90.953669 Derecesi, - 36.109997 Derece) , 0,589337).

  2. Radii r1 ve r2'yi (küre boyunca ölçülür) küre boyunca açılara dönüştürün. Tanım olarak, bir deniz mili (NM) 1/60 ark derecesidir (pi / 180 x 1/60 = 0,0002908888 radyan). Dolayısıyla açılar olarak

    r1 = 107.5 / 60 Degree = 0.0312705 radian
    r2 = 145 / 60 Degree = 0.0421788 radian
    
  3. Jeodezik x1 çevresinde yarıçapı r1 çemberi bir ile toprak yüzeyinin kesişimidir Öklid yarıçapı sin alanında (R1) (R1) * x1 cos merkezlenmiş.

  4. Cos (r1) * x1 etrafındaki günah yarıçapı küresi (r1) ile kesişme noktası tarafından belirlenen düzlem ve x1'e diktir ve cos (r1) x1 noktasından geçerek denkleminin x.x1 = cos olduğu (r1) ("." olağan nokta ürününü temsil eder ); diğer uçak için de aynı şekilde. X1 ve x2'nin doğrusal bir birleşimi olan bu iki düzlemin kesişme noktasında benzersiz bir x0 noktası olacaktır. Yazma x0 = a x1 + b * x2 iki düzlemsel denklem

    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
    

    Q olarak yazacağım x2.x1 = x1.x2 olduğu gerçeği kullanılarak çözüm (varsa) aşağıdakiler tarafından verilir:

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

    Çalışan örnekte, a = 0.973503 ve b = 0.0260194'ü hesaplarım.

    Açıkça q ^ 2! = 1'e ihtiyacımız var. Bu, x1 ve x2'nin ne aynı nokta ne de antipodal nokta olamayacağı anlamına gelir.

  5. Şimdi, iki düzlemin kesişme çizgisindeki diğer tüm noktalar, her iki düzlemde karşılıklı olarak dik olan bir vektörün n bir çarpımı tarafından x0'dan farklıdır. Çapraz ürün

    n = x1~Cross~x2
    

    n sağlanan iş sıfır değil mi: bir kez daha, bu, x1 ve x2'nin ne çakışan ne de çapsal olarak zıt olduğu anlamına gelir. (Çapraz ürünü yüksek hassasiyetle hesaplamaya özen göstermeliyiz, çünkü x1 ve x2 birbirine yakın olduğunda, çok fazla iptal içeren çıkarmaları içerir.) Örnekte, n = (0.0272194, -0.00631254, -0.00803124) .

  6. Bu nedenle, dünyanın yüzeyinde yatan x0 + t * n formunun iki noktasına kadar ararız: yani uzunlukları 1'e eşittir. Eşdeğer olarak, kare uzunlukları 1'dir:

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

    X0.n ifadesi yok olur çünkü x0 (x1 ve x2'nin doğrusal bir birleşimidir) n'ye diktir. İki çözüm kolayca

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

    ve olumsuz. Bir kez daha yüksek hassasiyet aranıyor, çünkü x1 ve x2 yakın olduğunda, x0.x0 1'e çok yakın, kayan nokta hassasiyetinde bir kayıp meydana geliyor. Örnekte, t = 1.07509 veya t = -1.07509. İki kesişme noktası bu nedenle eşit

    x0 + t*n = (0.0257661, -0.798332, 0.601666)
    x0 - t*n = (-0.0327606, -0.784759, 0.618935)
    
  7. Son olarak, bu çözümleri geocentric (x, y, z) 'yi coğrafi koordinatlara dönüştürerek geri (lat, lon)' a dönüştürebiliriz:

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

    Boylam için, -180 - 180 derece aralığındaki genelleştirilmiş geri dönen değerleri kullanın (hesaplama uygulamalarında bu işlev her ikisini de alır. y y'yi sadece y / x oranından ziyade argüman olarak ; bazen "ATan2" olarak da adlandırılır).

    Şekilde sarı noktalar olarak gösterilen iki çözeltiyi (-88.151426, 36.989311) ve (-92.390485, 38.238380) elde ediyorum.

3B şekil

Eksenler jeosantrik (x, y, z) koordinatlarını görüntüler. Gri yama, dünya yüzeyinin -95 ila -87 derece boylam, 33 ila 40 derece enlem (bir derece gratikül işaretli) kısmıdır. Dünyanın üç yüzeyi de göstermek için dünyanın yüzeyi kısmen saydamlaştırılmıştır. Hesaplanan çözümlerin doğruluğu sarı noktaların kürelerin kesişme noktalarında nasıl durduğuyla belirgindir.


Bill, bu harika. Uygulamaya çalışan birine dayanarak ekleyebileceğiniz bir açıklama. 2. adımda açıkça dereceden radyana dönüşüm vermezsiniz.
Jersey Andy,

@Jersey Önerilen düzenlemeniz için teşekkür ederiz. Artıklıktan kaçınmak ve formülleri olabildiğince açık tutmak için biraz değiştirdim. Bahsettiğiniz ipliği okuduktan sonra, nokta ürününü açıklamak için bir bağlantı da ekledim.
whuber

8

elipsoidal durum:

Bu problem, "medyan çizgileri" olarak tanımlanan deniz sınırlarının bulunmasının genelleşmesidir ve bu konuda geniş bir literatür bulunmaktadır. Bu soruna benim çözümüm, eşitlikçi azimut projeksiyonundan yararlanmaktır:

  1. Kesişme noktasında tahmin
  2. Eşitlikli bir azimut projeksiyonunun merkezi olarak bu tahmin edilen kesişme noktasını kullanarak iki baz noktayı yansıtın,
  3. Kavşak problemini 2d öngörülen uzayda çözün.
  4. Yeni kavşak noktası eskisinden çok uzakta, 2. adıma geri dönün.

Bu algoritma karesel olarak birleşir ve bir elipsoid üzerinde doğru bir çözüm sunar. (Balıkçılık, petrol ve maden haklarını belirlediği için deniz sınırları içerisinde doğruluk gereklidir.)

Formüller, bir elipsoit devrimin jeodezik bölüm 14'ünde verilmiştir . Elipsoidal eşit azimut projeksiyonu GeographicLib tarafından sağlanmaktadır . Bir elipsoid için Geodezik projeksiyonlarda bir MATLAB versiyonu mevcuttur .


+1 Bu harika bir makale: buradaki mütevazi tanımınız adalet yapmıyor.
whuber

Ayrıca benim daha kısa "Geodezikler Algoritmaları'nda" jeodezikler kağıt Bkz dx.doi.org/10.1007/s00190-012-0578-z Bu kağıtlar için (serbest indir!) Artı yanlışların ve ekini geographiclib.sf.net/geod-addenda.html
cffk

1

İşte bunu yapmak için bazı R kodu:

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

Aşağıdaki @ whuber cevabı , burada iki nedenden dolayı yararlıdır bazı Java kod:

  • ArcTan ile ilgili bir vurguyu vurgular (Java ve belki başka diller için?)
  • @ whuber'ın cevabında bahsedilmeyen de dahil olmak üzere olası kenar davalarını ele alır.

Optimize edilmiş veya tamamlanmamış (gibi açık sınıflar bıraktım Point), ama hile yapmalı.

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;
}

Ayrıca, önemlisi, kullanımına dikkat edin atan2- @ whuber'un cevabından beklediğinizin tam tersi (nedenini bilmiyorum ama işe yarıyor):

    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

@Wuhber answer için 'R' kodu çalışıyor.

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

Dairelerden biri Nortstar ise, o zaman birim kürenin en kolay yolu vardır.

Enleminizi Nortstar ile ölçebilirsiniz. O zaman bu alanda göreceli bir konum var. v1 (0, sin (la), cos (la)) Başka bir yıldızın (yıldız2) pozisyonunu almanaktan biliyorsunuz. v2 (günah (lo2) * cos (la2), günah (la2), cos (lo2) * cos (la2)) Vektörleri. Küre denkleminden.

lo2 göreceli boylamdır. Onun unknow .

Siz ve yıldız2 arasındaki açı, siz de ölçebilirsiniz, (m) Ve biliyorsunuz, iki birim vektörün iç ürünü, cos (açı) arasındadır. cos (m) = nokta (v1, v2) u şimdi göreceli boylamı (lo2) hesaplayabilir. LO2 = acos ((cos (m) -sin (la) * sin (la2) ') / (cos (la) * cos (la2)'))

Ne de olsa, star2'nin gerçek boylamını lo2'ye ekleyin. (veya alt, sizden veya doğudan batı tarafına bağlı olarak değişir.) lo2 şimdi sizin boylamınız.

İngilizcem için üzgünüm, bu dili asla öğrenemiyorum.


2 şey: Northstar kutup yıldızı demek.

Bir diğeri. Çünkü açı horizont'a göre ölçülür, daima 90 açı düzeltmesi gerekir. M açısı için de geçerlidir.

ps: gerçek açı ortalaması: yıldız konumu - zaman düzeltme.


Bunun soruyu nasıl cevapladığı belli değil.
whuber
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.