2011-11-14 34 views
13

Tôi đang cố gắng phát triển động cơ thực tế tăng cường của riêng mình.Tính toán vòng bi giữa hai vị trí (vĩ độ, dài)

Tìm kiếm trên internet, tôi thấy hữu ích này tutorial. Đọc nó tôi thấy rằng điều quan trọng là mang giữa vị trí người dùng, vị trí điểm và phía bắc.

Hình ảnh sau đây là từ hướng dẫn đó.

enter image description here

Sau đó, tôi đã viết một phương pháp Objective-C để có được phiên bản beta:

+ (float) calculateBetaFrom:(CLLocationCoordinate2D)user to:(CLLocationCoordinate2D)destination 
{ 
    double beta = 0; 
    double a, b = 0; 

    a = destination.latitude - user.latitude; 
    b = destination.longitude - user.longitude; 

    beta = atan2(a, b) * 180.0/M_PI; 
    if (beta < 0.0) 
     beta += 360.0; 
    else if (beta > 360.0) 
     beta -= 360; 

    return beta; 
} 

Tuy nhiên, khi tôi thử nó, nó không hoạt động rất tốt.

Vì vậy, tôi đã kiểm tra Bộ công cụ AR của iPhone, để xem cách nó hoạt động (Tôi đã làm việc với bộ công cụ này, nhưng nó là quá lớn đối với tôi).

Và, trong ARGeoCoordinate.m có một thực hiện như thế nào để có được phiên bản beta:

- (float)angleFromCoordinate:(CLLocationCoordinate2D)first toCoordinate:(CLLocationCoordinate2D)second { 

    float longitudinalDifference = second.longitude - first.longitude; 
    float latitudinalDifference  = second.latitude - first.latitude; 
    float possibleAzimuth   = (M_PI * .5f) - atan(latitudinalDifference/longitudinalDifference); 

    if (longitudinalDifference > 0) 
     return possibleAzimuth; 
    else if (longitudinalDifference < 0) 
     return possibleAzimuth + M_PI; 
    else if (latitudinalDifference < 0) 
     return M_PI; 

    return 0.0f; 
} 

Nó sử dụng công thức này:

float possibleAzimuth = (M_PI * .5f) - atan(latitudinalDifference/longitudinalDifference); 

Tại sao (M_PI * .5f) trong công thức này? Tôi không hiểu.

Và tiếp tục tìm kiếm, tôi đã tìm thấy một số khác page nói về cách tính khoảng cách và vòng bi của 2 vị trí. Trong trang này có một triển khai khác:

/** 
* Returns the (initial) bearing from this point to the supplied point, in degrees 
* see http://williams.best.vwh.net/avform.htm#Crs 
* 
* @param {LatLon} point: Latitude/longitude of destination point 
* @returns {Number} Initial bearing in degrees from North 
*/ 
LatLon.prototype.bearingTo = function(point) { 
    var lat1 = this._lat.toRad(), lat2 = point._lat.toRad(); 
    var dLon = (point._lon-this._lon).toRad(); 

    var y = Math.sin(dLon) * Math.cos(lat2); 
    var x = Math.cos(lat1)*Math.sin(lat2) - 
      Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon); 
    var brng = Math.atan2(y, x); 

    return (brng.toDeg()+360) % 360; 
} 

Cái nào là đúng?

+0

Bạn đã bao giờ giải quyết vấn đề này chưa? Tôi quan tâm đến giải pháp bạn đã đi với – Craigy

+0

Có, tôi phải thêm câu trả lời của riêng mình ngay. – VansFannel

Trả lời

14

Tính mang

//Source 
JSONObject source = step.getJSONObject("start_location"); 
double lat1 = Double.parseDouble(source.getString("lat")); 
double lng1 = Double.parseDouble(source.getString("lng")); 

// destination 
JSONObject destination = step.getJSONObject("end_location"); 
double lat2 = Double.parseDouble(destination.getString("lat")); 
double lng2 = Double.parseDouble(destination.getString("lng")); 

double dLon = (lng2-lng1); 
double y = Math.sin(dLon) * Math.cos(lat2); 
double x = Math.cos(lat1)*Math.sin(lat2) - Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon); 
double brng = Math.toDegrees((Math.atan2(y, x))); 
brng = (360 - ((brng + 360) % 360)); 

Chuyển đổi Degrees vào radian

Radians = Degrees * PI/180 

Chuyển đổi radian vào Degrees

Degrees = Radians * 180/PI 
+0

Bạn chuyển đổi giá trị thành độ, nhưng không phải là Vĩ độ và Kinh độ theo độ? Bạn không nên chuyển đổi chúng thành radian trước? – ravemir

+0

Tôi không chuyển đổi vĩ độ và kinh độ trong bán kính. Tôi không nghĩ rằng nó làm cho bất kỳ sự khác biệt –

+0

Bạn đã thử trận đấu mang trực tuyến để thử nghiệm? cho ví dụ. kiểm tra bởi liên kết này. http://www.sunearthtools.com/tools/distance.php –

4

Trong công thức

float possibleAzimuth = (M_PI * .5f) - atan(latitudinalDifference/longitudinalDifference);

thuật ngữ (M_PI * .5f) nghĩa π/2 là 90 °. Điều đó có nghĩa rằng đó là công thức tương tự mà bạn đã nêu lúc đầu, bởi vì liên quan đến hình trên nó giữ

β = arctan (a/b) = 90 ° - arctan (b/a).

Vì vậy, cả hai công thức đều giống nhau nếu a đề cập đến sự khác biệt về kinh độ và b ở chênh lệch vĩ độ. Công thức cuối cùng tính toán một lần nữa bằng cách sử dụng phần đầu tiên của phương trình của tôi.

+0

Bạn tham khảo 'a' là sự khác biệt trong lat và 'b' là sự khác biệt về lâu dài. Xem phản ứng của tôi về cách 'a' thực sự là sự khác biệt trong dài và' b' sự khác biệt trong lat. Nó có thể hữu ích để chỉnh sửa câu trả lời của bạn để phù hợp với sơ đồ vì vậy chúng tôi không nhầm lẫn giữa các độc giả trong tương lai hơn bất kỳ điều gì cần thiết? – Dolbz

+0

Cảm ơn bạn, Dolbz, bạn đúng, a và b nên được thay đổi. Tôi đã chỉnh sửa câu trả lời chính của mình để có câu trả lời đúng. :) – Palund

2

a trong biểu đồ là chênh lệch kinh độ, b là chênh lệch vĩ độ do đó trong phương pháp bạn đã viết bạn đã tạo cho chúng vòng tròn sai.

a = destination.latitude - user.latitude; // should be b 
b = destination.longitude - user.longitude; // should be a 

Hãy thử chuyển đổi chúng và xem điều gì sẽ xảy ra.

Xem phản hồi của Palund về câu trả lời cho các câu hỏi còn lại của bạn.

+0

Cảm ơn, bạn đã đúng: Tôi đã phạm sai lầm với a và b. Tôi đã chuyển đổi chúng và tôi nhận được bản beta = 9 độ. Nhưng, nếu tôi sử dụng LatLon.prototype.bearingTo, với cùng địa điểm, tôi nhận được beta = 7 độ. Tôi nghĩ rằng thứ hai là chính xác hơn, nhưng tôi không hiểu nó không được triển khai trong Bộ công cụ AR của iPhone. Cảm ơn một lần nữa. – VansFannel

+0

Điều này giải quyết vấn đề. Chỉ cần sử dụng arctan (b, a) thay vì (a, b). –

0

Nếu bạn muốn, bạn có thể xem mã được sử dụng trong mixare engine tăng cường thực tế, trên github và có phiên bản iPhone: github.com/mixare

+0

Cảm ơn. Tôi thấy bây giờ bạn đã làm việc với trình duyệt ar này. Bạn có thể giúp tôi tìm lớp học nào có tính toán vòng bi không? – VansFannel

+1

Xin chào, tôi không phải là nhà phát triển phiên bản iPhone nhưng theo tài liệu lớp học có sẵn tại: http://code.google.com/p/mixare/wiki/FileResponsibility nó sẽ là lớp AugmentedViewController. Nguồn là: https://github.com/mixare/mixare-iphone/blob/master/Classes/gui/tabbarControllers/augmentedView/AugmentedViewController.m – Daniele

7

Tôi biết câu hỏi này là cũ, nhưng đây là một giải pháp dễ dàng hơn:

float bearing = loc1.bearingTo (loc2);

1

Hãy thử điều này cho kết quả chính xác:

private static double degreeToRadians(double latLong) { 
    return (Math.PI * latLong/180.0); 
} 

private static double radiansToDegree(double latLong) { 
    return (latLong * 180.0/Math.PI); 
} 

public static double getBearing() { 

//Source 
JSONObject source = step.getJSONObject("start_location"); 
double lat1 = Double.parseDouble(source.getString("lat")); 
double lng1 = Double.parseDouble(source.getString("lng")); 

// destination 
JSONObject destination = step.getJSONObject("end_location"); 
double lat2 = Double.parseDouble(destination.getString("lat")); 
double lng2 = Double.parseDouble(destination.getString("lng")); 

    double fLat = degreeToRadians(lat1); 
    double fLong = degreeToRadians(lng1); 
    double tLat = degreeToRadians(lat2); 
    double tLong = degreeToRadians(lng2); 

    double dLon = (tLong - fLong); 

    double degree = radiansToDegree(Math.atan2(sin(dLon) * cos(tLat), 
      cos(fLat) * sin(tLat) - sin(fLat) * cos(tLat) * cos(dLon))); 

    if (degree >= 0) { 
     return degree; 
    } else { 
     return 360 + degree; 
    } 
} 

Bạn có thể kiểm tra kết quả mang về http://www.sunearthtools.com/tools/distance.php.

Các vấn đề liên quan