3 अक्षांश / देशांतर अंक, और 3 दूरियों का उपयोग करके त्रयीकरण?


34

मैं एक अज्ञात लक्ष्य स्थान (अक्षांश और देशांतर निर्देशांक) का पता लगाना चाहता हूं। 3 ज्ञात बिंदु (अक्षांश और देशांतर समन्वय जोड़े) हैं और प्रत्येक बिंदु के लिए लक्ष्य स्थान के किलोमीटर में दूरी है। मैं लक्ष्य स्थान के निर्देशांक की गणना कैसे कर सकता हूं?

उदाहरण के लिए, मान लें कि मेरे पास निम्नलिखित डेटा बिंदु हैं

37.418436,-121.963477   0.265710701754km
37.417243,-121.961889   0.234592423446km
37.418692,-121.960194   0.0548954278262km

मुझे जो पसंद है, वह उस फ़ंक्शन के लिए गणित है जो इनपुट के रूप में लेता है और आउटपुट के रूप में 37.417959, -121.961954 देता है।

मैं समझता हूं कि http://www.movable-type.co.uk/scripts/latlong.html से दो बिंदुओं के बीच की दूरी की गणना कैसे करें, मैं सामान्य सिद्धांत को समझता हूं कि इन जैसे तीन सर्कल के साथ आपको ओवरलैप के बिल्कुल एक बिंदु मिलते हैं। इस इनपुट के साथ उस बिंदु की गणना करने के लिए आवश्यक गणित क्या है, मैं जल्दबाजी में हूं।


यहां एक पृष्ठ है जो आपको तीन निर्देशांक के केंद्र को खोजने के गणित के माध्यम से चलता है। शायद यह किसी तरह से मदद कर सकता है। < mathforum.org/library/drmath/view/68373.html >
जॉन

1
क्या यह गोले / गोलाकार पर होना चाहिए, या एक प्लानर एल्गोरिथ्म ठीक है?
बजे

1
मैं आपको जवाब नहीं दे सकता, लेकिन मुझे लगता है कि मैं आपको सही दिशा में इंगित कर सकता हूं। तीन निर्देशांक = तीन केंद्र बिंदु। तीन दूरी = तीन वृत्त। दो सर्कल जो प्रतिच्छेद करते हैं, उनमें से कोई भी / एक / दो समाधान की संभावना हो सकती है। तीन सर्किलों के पास इसके समाधान के रूप में कोई नहीं / एक / या एक क्षेत्र हो सकता है। तीन सर्कल के लिए सर्कल सूत्र प्राप्त करें, और इसे समीकरणों / बीजगणित के सिस्टम के साथ हल करें।
क्रेजीएनिग्मा

वास्तव में, आपको इसे हल करने के लिए सिस्टम की भी आवश्यकता नहीं है। एक या दो संभावनाएं हैं, लेकिन चूंकि आपके पास एक दूरी का मूल्य है, आप सही उत्तर को अलग कर सकते हैं।
जॉर्ज सिल्वा

1
+1 यह एक अच्छा सवाल है। पहले मुझे लगा कि एक समाधान आसानी से Google के साथ मिल सकता है, लेकिन स्पष्ट रूप से नहीं। शायद यह समस्या आमतौर पर अधिक बताई जा सकती है: प्रत्येक बिंदु के साथ एन अंक दिए गए हैं, जिसमें न केवल एक दूरी है, बल्कि त्रुटि का एक मार्जिन है, आत्मविश्वास दीर्घवृत्त ढूंढें।
कर्क कुक्केंडल

जवाबों:


34

कुछ विकिपीडिया पर देखने के बाद और StackOverflow में एक ही सवाल / जवाब के बाद , मुझे लगा कि मैं इस पर एक छुरा लूँगा, और अंतराल में भरने की कोशिश करूँगा।

सबसे पहले, निश्चित नहीं है कि आपको आउटपुट कहाँ मिला है, लेकिन यह गलत प्रतीत होता है। मैंने ArcMap में बिंदुओं को प्लॉट किया, उन्हें निर्दिष्ट दूरी पर बफ़र किया, बफ़र्स पर इंटरसेक्ट किया, और फिर समाधान प्राप्त करने के लिए चौराहे के शीर्ष पर कब्जा कर लिया। आपका प्रस्तावित आउटपुट हरे रंग में है। मैंने कॉलआउट बॉक्स में मूल्य की गणना की, जो कि आर्कपेक को प्रतिच्छेद से प्राप्त समाधान के लिए दिए गए 3 मीटर के बारे में है।

वैकल्पिक शब्द

विकिपीडिया पृष्ठ पर गणित बहुत बुरा नहीं है, बस कार्टिसियन ईसीईएफ को अपने भू-निर्देशांक को गुप्त करने की आवश्यकता है, जो यहां पाया जा सकता है । यदि आप एक दीर्घवृत्त का उपयोग नहीं कर रहे हैं, तो a / x + h शब्दों को ऑटिहेल क्षेत्र त्रिज्या द्वारा प्रतिस्थापित किया जा सकता है।

शायद सबसे आसान बस आपको कुछ अच्छी तरह से (?) दस्तावेज कोड दिया गया है, इसलिए यहां यह अजगर में है

import math
import numpy

#assuming elevation = 0
earthR = 6371
LatA = 37.418436
LonA = -121.963477
DistA = 0.265710701754
LatB = 37.417243
LonB = -121.961889
DistB = 0.234592423446
LatC = 37.418692
LonC = -121.960194
DistC = 0.0548954278262

#using authalic sphere
#if using an ellipsoid this step is slightly different
#Convert geodetic Lat/Long to ECEF xyz
#   1. Convert Lat/Long to radians
#   2. Convert Lat/Long(radians) to ECEF
xA = earthR *(math.cos(math.radians(LatA)) * math.cos(math.radians(LonA)))
yA = earthR *(math.cos(math.radians(LatA)) * math.sin(math.radians(LonA)))
zA = earthR *(math.sin(math.radians(LatA)))

xB = earthR *(math.cos(math.radians(LatB)) * math.cos(math.radians(LonB)))
yB = earthR *(math.cos(math.radians(LatB)) * math.sin(math.radians(LonB)))
zB = earthR *(math.sin(math.radians(LatB)))

xC = earthR *(math.cos(math.radians(LatC)) * math.cos(math.radians(LonC)))
yC = earthR *(math.cos(math.radians(LatC)) * math.sin(math.radians(LonC)))
zC = earthR *(math.sin(math.radians(LatC)))

P1 = numpy.array([xA, yA, zA])
P2 = numpy.array([xB, yB, zB])
P3 = numpy.array([xC, yC, zC])

#from wikipedia
#transform to get circle 1 at origin
#transform to get circle 2 on x axis
ex = (P2 - P1)/(numpy.linalg.norm(P2 - P1))
i = numpy.dot(ex, P3 - P1)
ey = (P3 - P1 - i*ex)/(numpy.linalg.norm(P3 - P1 - i*ex))
ez = numpy.cross(ex,ey)
d = numpy.linalg.norm(P2 - P1)
j = numpy.dot(ey, P3 - P1)

#from wikipedia
#plug and chug using above values
x = (pow(DistA,2) - pow(DistB,2) + pow(d,2))/(2*d)
y = ((pow(DistA,2) - pow(DistC,2) + pow(i,2) + pow(j,2))/(2*j)) - ((i/j)*x)

# only one case shown here
z = numpy.sqrt(pow(DistA,2) - pow(x,2) - pow(y,2))

#triPt is an array with ECEF x,y,z of trilateration point
triPt = P1 + x*ex + y*ey + z*ez

#convert back to lat/long from ECEF
#convert to degrees
lat = math.degrees(math.asin(triPt[2] / earthR))
lon = math.degrees(math.atan2(triPt[1],triPt[0]))

print lat, lon

1
मैं एक समान उत्तर देने जा रहा था, लेकिन अब इसकी कोई आवश्यकता नहीं है! मेरा उत्थान हो जाता है।
जुरा

बचाव के लिए सुन्न! यह तब संकलित करता है जब 'triPt' को 'triLatPt' से बदल दिया जाता है, लेकिन अन्यथा 37.4191023738 -121.960579208 वापस करता है। अच्छी नौकरी
वुल्फऑर्ड्रेड

अच्छा कार्य! अगर मैं भौगोलिक समन्वय प्रणाली को एक स्थानीय [कार्टेशियन] समन्वय प्रणाली में बदल दूं, तो क्या यह अभी भी काम करेगा?
zengr

सी ++ डोमेन में उन लोगों के लिए..एक साथ एक वास्तविक त्वरित एक pastebin.com/9Dur6RAP
raaj

2
धन्यवाद @ ह्विक! मैंने इसे जावास्क्रिप्ट में रखा है (नोड के लिए अभिप्राय, लेकिन ब्राउज़र में काम करने के लिए आसानी से परिवर्तित किया जा सकता है)। gist.github.com/dav-/bb7103008cdf9359887f
DC_

6

मुझे यकीन नहीं है कि अगर मैं अनुभवहीन हूं, लेकिन, यदि आप प्रत्येक बिंदु को आकार से बफर करते हैं, और फिर सभी तीन मंडलियों को काटते हैं जो आपको सही स्थान प्राप्त करेंगे?

आप स्थानिक एपीआई का उपयोग करके चौराहे की गणना कर सकते हैं। उदाहरण:

  • GeoScript
  • जावा टोपोलॉजी सूट
  • नेट टोपोलॉजी सूट
  • GEOS

1
वास्तव में, वह उस चौराहे बिंदु को प्राप्त करने के लिए सूत्रों में रुचि रखता है।
विंको व्रसालोविक

एक स्थानिक एपीआई का उपयोग करके आप इसे शुद्ध गणित का उपयोग किए बिना कर सकते हैं।
जॉर्ज सिल्वा

1
क्या आप ऐसे एपीआई का उदाहरण दे सकते हैं?
नोहट

नोहाट के अनुरोध को प्रतिबिंबित करने के लिए संपादित पोस्ट।
जॉर्ज सिल्वा

+1, अच्छी पार्श्व सोच, भले ही सबसे कम्प्यूटेशनल रूप से कुशल न हो!
जगंल

2

निम्नलिखित नोट प्लानरिथिमिक ज्यामिति का उपयोग करते हैं (यानी आपको अपने निर्देशांक को एक उपयुक्त स्थानीय समन्वय प्रणाली में प्रोजेक्ट करना होगा)।

पायथन में एक उदाहरण के साथ मेरा तर्क, इस प्रकार है:

डेटा-पॉइंट्स में से 2 लें (उन्हें कॉल करें aऔर b)। हमारे लक्ष्य बिंदु को कॉल करें x। हम पहले से ही दूरी axऔर जानते हैं bx। हम abपाइथागोरस के प्रमेय का उपयोग करके दूरी की गणना कर सकते हैं ।

>>> import math
>>> a = (1, 4)
>>> b = (3, 6)
>>> dist_ax = 3
>>> dist_bx = 5.385
# Pythagoras's theorem
>>> dist_ab = math.sqrt(abs(a[0]-b[0])**2 + abs(a[1]-b[1])**2)
>>> dist_ab
2.8284271247461903

अब, आप इन रेखाओं के कोणों को बाहर निकाल सकते हैं:

>>> angle_abx = math.acos((dist_bx * dist_bx + dist_ab * dist_ab - dist_ax * dist_ax)/(2 * dist_bx * dist_ab))
>>> math.degrees(angle_abx)
23.202973815040256
>>> angle_bax = math.acos((dist_ax * dist_ax + dist_ab * dist_ab - dist_bx * dist_bx)/(2 * dist_ax * dist_ab))
>>> math.degrees(angle_bax)
134.9915256259537
>>> angle_axb = math.acos((dist_ax * dist_ax + dist_bx * dist_bx - dist_ab * dist_ab)/(2 * dist_ax * dist_bx))
>>> math.degrees(angle_axb)
21.805500559006095

दुर्भाग्य से मैं आपके लिए जवाब पूरा करने के लिए समय पर छोटा हूं, हालांकि, अब आप कोण जानते हैं, तो आप दो संभावित स्थानों की गणना कर सकते हैं x। फिर, तीसरे बिंदु c का उपयोग करके आप गणना कर सकते हैं कि कौन सा स्थान सही है।


2

यह काम कर सकता है। अजगर में फिर से, आप इसे एक फ़ंक्शन xN, yN = बिंदुओं के निर्देशांक, r1 & r2 = त्रिज्या मानों के शरीर में रख सकते हैं

dX = x2 - x1
dY = y2 - y1

centroidDistance = math.sqrt(math.pow(e,2) + math.pow(dY,2)) #distance from centroids
distancePL = (math.pow(centroidDistance,2) + (math.pow(r1,2) - math.pow(r2,2))) / (2 * centroidDistance) #distance from point to a line splitting the two centroids

rx1 = x1 + (dX *k)/centroidDistance + (dY/centroidDistance) * math.sqrt(math.pow(r1,2) - math.pow(distancePL,2))
ry1 = y1 + (dY*k)/centroidDistance - (dX /centroidDistance) * math.sqrt(math.pow(r1,2) - math.pow(distancePL,2))

rx2 = x1 + (dX *k)/centroidDistance - (dY/centroidDistance) * math.sqrt(math.pow(r1,2) - math.pow(distancePL,2))
ry2 = y1 + (dY*k)/centroidDistance + (dX /centroidDistance) * math.sqrt(math.pow(r1,2) - math.pow(distancePL,2))

rx और ry मान एक वृत्त पर दो चौराहों के बिंदुओं का रिटर्न मान (सरणी में होना चाहिए) है, अगर यह स्पष्ट करने में मदद करता है।

पहले 2 हलकों के लिए ऐसा करें, फिर पहले और आखिरी के लिए। यदि पहली पुनरावृति के परिणामों में से कोई भी दूसरे (कुछ सहिष्णुता के भीतर, शायद) के परिणामों के साथ तुलना करता है, तो आपके पास चौराहे का बिंदु है। यह एक महान समाधान नहीं है, खासकर जब आप इस प्रक्रिया में अंकों से अधिक जोड़ना शुरू करते हैं, लेकिन सबसे सरल है जो मैं समीकरणों को हल करने के लिए जाने के बिना देख सकता हूं।


आपके कोड में 'e' और 'k' क्या हैं?
ReinierDG

मुझे याद नहीं है कि अगर आप सिर्फ तीन सर्किल हैं तो wwnick का उत्तर कुछ ऐसी लाइनों के साथ अधिक है जिन्हें आप लागू करना चाहते हैं।
वोल्फऑड्रेड

1

आप पोस्टगिस (St_Intersection, St_buffer फ़ंक्शन) से स्थानिक API का उपयोग कर सकते हैं। जैसा कि ध्यान दिया गया है, आपको यह भी याद रखना चाहिए कि Postgis प्लानर एल्गोरिदम का उपयोग करता है, लेकिन छोटे क्षेत्रों के लिए, समान-दूर की आपत्ति का उपयोग करने से बहुत त्रुटि नहीं होती है।


PostGIS GEOGRAPHYप्रकार के बजाय प्रकार का उपयोग करके गोलाकार गणना कर सकते हैं GEOMETRY
जूल

1

इसे PHP भाषा में करें:

// ऊँचाई ग्रहण करना = ०
$ अर्थ = 6371; // किमी में (= 3959 मील में)

$ LatA = 37.418436;
$ लोना = -121.963477;
$ DistA = 0.265710701754;

$ LatB = 37.417243;
$ लोएनबी = -121.961889;
$ DistB = 0.234592423446;

$ LatC = 37.418692;
$ एलओसी = -121.960194;
$ DistC = 0.0548954278262;

/ *
# ऑटिस्टिक क्षेत्र का उपयोग करना
# एक दीर्घवृत्त का उपयोग करते हुए यह कदम थोड़ा अलग है
#Convert geodetic Lat / Long से ECEF xyz
# 1. रेडियों से लैट / लॉन्ग कनेक्ट करें
2. "ECEF में लैट / लॉन्ग (रेडियंस) कन्वर्ट करें
* /
$ xA = $ EarthR * (cos (deg2rad ($ LatA)) * cos (deg2rad ($ लोना)));
$ yA = $ earthR * (cos (deg2rad ($ LatA)) * sin (deg2rad ($ लोना)));
$ zA = $ earthR * (sin (deg2rad ($ LatA)));

$ xB = $ EarthR * (cos (deg2rad ($ LatB)) * cos (deg2rad ($ LonB)));
$ yB = $ earthR * (cos (deg2rad ($ LatB)) * sin (deg2rad ($ LonB)));
$ zB = $ earthR * (sin (deg2rad ($ LatB)));

$ xC = $ earthR * (cos (deg2rad ($ LatC)) * cos (deg2rad ($ LonC)));
$ yC = $ earthR * (cos (deg2rad ($ LatC)) * sin (deg2rad ($ LonC)));
$ zC = $ earthR * (sin (deg2rad ($ LatC)));

/ *
इंस्टॉल करें:
sudo नाशपाती स्थापित करें Math_Vector-0.7.0
sudo नाशपाती स्थापित Math_Matrix-0.8.7
* /
// PEAR को शामिल करें :: Math_Matrix
// /usr/share/php/Math/Matrix.php
// शामिल_पथ = "।: / usr / स्थानीय / php / नाशपाती /"
requirement_once 'Math / Matrix.php';
requirement_once 'Math / वेक्टर.php';
requirement_once 'Math / वेक्टर3.php';


$ P1vector = नया Math_Vector3 (सरणी ($ xA, $ yA, $ zA));
$ P2vector = नया Math_Vector3 (सरणी ($ xB, $ yB, $ zB));
$ P3vector = नया Math_Vector3 (सरणी ($ xC, $ yC, $ zC));

#from विकिपीडिया: http://en.wikipedia.org/wiki/Trilateration
#transform मूल में सर्कल 1 प्राप्त करने के लिए
# एक्सरे पर सर्कल 2 प्राप्त करने के लिए ट्रांसफॉर्मर

// CALC EX
$ P2minusP1 = Math_VectorOp :: घटाना ($ P2vector, $ P1vector);
$ l = new Math_Vector ($ P2minusP1);
$ P2minusP1_length = $ l-> लंबाई ();
$ मान = नया Math_Vector3 (सरणी ($ P2minusP1_length, $ P2minusP1_length, $ P2minusP1_length);
$ d = $ मानदंड; // कैल्क डी बचाओ
$ ex = Math_VectorOp :: divide ($ P2minusP1, $ norm);
// इको "पूर्व:"। $ ex-> toString ()। "\ n";
$ ex_x = floatval ($ ex -> _ tuple-> getData () [0]);
$ ex_y = floatval ($ ex -> _ tuple-> getData () [1]);
$ ex_z = floatval ($ ex -> _ tuple-> getData () [2]);
$ ex = new Math_Vector3 (सरणी ($ ex_x, $ ex_y, $ ex_z));

// CALC i
$ P3minusP1 = Math_VectorOp :: घटाना ($ P3vector, $ P1vector);
$ P3minusP1_x = floatval ($ P3minusP1 -> _ tuple-> getData () [0]);
$ P3minusP1_y = floatval ($ P3minusP1 -> _ tuple-> getData () [1]);
$ P3minusP1_z = floatval ($ P3minusP1 -> _ tuple-> getData () [2]);
$ P3minusP1 = नया Math_Vector3 (सरणी (P3minusP1_x, $ P3minusP1_y, $ P3minusP1_z));
$ i = Math_VectorOp :: dotProduct ($ ex, $ P3minusP1);
// इको "i = $ i \ n";

// CALC EY
$ iex = Math_VectorOp :: स्केल ($ i, $ ex);
// इको "iex ="। $ iex-> toString ()। "\ n";
$ P3P1iex = Math_VectorOp :: घटाना ($ P3minusP1, $ iex);
// इको "P3P1iex ="। $ P3P1iex-> toString (); "\ n";
$ l = new Math_Vector ($ P3P1iex);
$ P3P1iex_length = $ l-> लंबाई ();
$ मान = नया Math_Vector3 (सरणी (P3P1iex_length, $ P3P1iex_length, $ P3P1iex_length);
// इको "मानदंड:"। $ मानक-> toString ()। "\ n";
$ आँख = Math_VectorOp :: विभाजित ($ P3P1iex, $ मानदंड);
// इको "आई ="। $ आई-> स्ट्रींग ()। "\ n";
$ आई_एक्स = फ्लोटवल ($ आंख -> टुपल-> गेटडाटा () [0]);
$ आई_य = फ्लोटवल ($ आंख -> टुपल-> गेटडाटा () [1]);
$ आई_ज = फ्लोटवल ($ आंख -> टुपल-> गेटडाटा () [2]);
$ आँख = नया गणित_वेक्टर 3 (सरणी ($ ey_x, $ ey_y, $ ey_z));

// CALC EZ
$ ez = Math_VectorOp :: crossProduct ($ ex, $ eye);
// echo "ez ="। $ ez-> toString ()। "\ n";

// CALC D
// इसे पहले करें
$ d = फ्लोटवल ($ d -> _ tuple-> getData () [0]);
// इको "d = $ d \ n";

// CALC जे
$ j = Math_VectorOp :: dotProduct ($ आंख, $ P3minusP1);
// इको "j = $ j \ n";

#from wikipedia
उपरोक्त मूल्यों का उपयोग करते हुए #plug और chug
$ x = (पॉव ($ DistA, 2) - pow ($ DistB, 2) + pow ($ d, 2)) / (2 * $ d);
$ y = ((pow ($ DistA, 2) - pow ($ DistC, 2) + pow ($ i, 2) + pow ($ j, 2)) / (२ * $ j)) - ($ i) / $ जे) * $ x);

# केवल एक मामला यहां दिखाया गया है
$ z = sqrt (pow ($ DistA, 2) - pow ($ x, 2) - pow ($ y, 2)));

// इको "x = $ x - y = $ y - z = $ z \ n";

#triPt, ECEF x, y, त्रयी बिंदु के z के साथ एक सरणी है
$ xex = Math_VectorOp :: स्केल ($ x, $ ex);
$ yey = Math_VectorOp :: स्केल ($ y, $ आंख);
$ zez = Math_VectorOp :: स्केल ($ z, $ ez);

// CALC $ triPt = $ P1vector + $ xex + $ yey + $ zez;
$ triPt = Math_VectorOp :: add ($ P1vector, $ xex);
$ triPt = Math_VectorOp :: add ($ triPt, $ yey);
$ triPt = Math_VectorOp :: add ($ triPt, $ zez);
// इको "triPt ="। $ triPt-> toString ()। "\ n";
$ triPt_x = floatval ($ triPt -> _ tuple-> getData () [0]);
$ triPt_y = floatval ($ triPt -> _ tuple-> getData () [1]);
$ triPt_z = floatval ($ triPt -> _ tuple-> getData () [2]);


# ईसीईएफ से लैट / लंबे समय तक वापस
# डिग्री पर वापस जाएं
$ lat = rad2deg (असिन ($ triPt_z / $ earthR));
$ लोन = rad2deg (atan2 ($ triPt_y, $ triPt_x));

गूंज $ लैट। ','। देशा $;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.