2012-11-14 11 views
6

Czy istnieje wbudowana funkcja w C++ lub C bibliotek, które mogą być wykorzystane, aby znaleźć odległość między dwoma punktami w przestrzeni 2-DWbudowana funkcja znaleźć dystans

PS: wiem, jak wdrożyć go samodzielnie.

+5

Istnieje nieskończenie wiele ważnych "funkcji odległościowych" na przestrzeni 2D. Jak ktokolwiek powinien wiedzieć, który z nich chcesz? –

+3

Nie ma nawet wbudowanej struktury danych dla punktów ... –

+5

@KerrekSB Metryka francuskiej kolei, oczywiście. –

Odpowiedz

5

Cóż, można użyć arytmetyki na complex numbers:

using point_t = std::complex<int>; 

double distance(point_t a, point_t b) { 
    std::sqrt(norm(b - a)) 
} 

Zdaję sobie sprawę, że to nie całkiem spełnić swoje wymagania nie pisania własnych funkcji, ale logika jest rzeczywista odległość zaimplementowane w std::norm function. Po prostu zwraca kwadrat odległości.

+2

Z pewnych ograniczonych doświadczeń sugerowałbym rozważenie, czy pierwiastek kwadratowy jest rzeczywiście konieczną operacją. Często możesz rozwiązać wszystkie problemy z odległością do kwadratu (pamiętając, że kwadratura jest monotoniczna), więc nie ma potrzeby utrzymywania tej kosztownej operacji. –

+1

@KerrekSB * Jeśli * musisz tylko porównać odległości, tak. Chciałem jednak zachować odpowiedź na ten temat i nie chciałem zakładać konkretnego przypadku użycia. –

+0

Czy mogą wystąpić jakieś błędy w przypadku zastąpienia powyższego ciała przez 'std :: abs (b-a)'? (['std :: abs' od' std :: complex'] (http://en.cppreference.com/w/cpp/numeric/complex/abs))? Porównanie implementacji 'std :: norm' i' std :: abs' [w libstdC++] (https://gc.gnu.org/onlinedocs/gcc-4.6.3/libstdc++/api/a00812_source.html), wydaje się, że ten drugi modyfikuje długość rzeczywistego i złożonego komponentu do najdłuższego z nich, przed ich wyrównaniem. Użycie podejścia 'std :: norm' nie spowoduje żadnej takiej" normalizacji komponentów ". Co może być w górę/w dół do stosowania podejścia 'std :: abs' (impl.)? – dfri

1

Nie, ponieważ wektor 2D nie jest typem części języka.

W zależności od potrzeb dostępnych jest wiele bibliotek matematycznych/gier/symulacji, które implementują obiekty współrzędnych 2D i zapewnią funkcje umożliwiające znalezienie odległości między takimi punktami.

+0

dlaczego nie po prostu funkcja z podpisem 'podwójna odległość (x1, x2, y1, y2)'? – none

+0

Ponieważ nie jest to "wbudowane" - jeśli wbudowane oznacza "część języka lub standardowe biblioteki", tak jak myślę, że to jest – emartel

1

Więc myślę, że to jest łatwe do znalezienia:

liniowa odległość pomiędzy dwoma punktami w przestrzeni 3D.

d = sqrt ((x2 - x 1)^2 + (Y2 - Y 1)^2 + (Z2 - Z1)^2)

Odległość Manhattan różni się bardzo w 2D gry:

d = | (x2 - x1) | + | (y2 - y1) |

typedef struct { 
    float x, y, z; 
} point_t; 

typedef struct { 
    int x, y; 
} point2d_t; 

double distanceFinder(point_t a, point_t b) 
{ 
    return sqrt(pow(a.x-b.x, 2.0) + pow(a.y-b.y, 2.0) + pow(a.z-b.z, 2.0)); 
} 

int manhattanFinder(point2d_t a, point2d_t b) 
{ 
    /* Considering the points have integer coordinates and is a 2D game */ 
    return abs(a.x - b.x) + abs(a.y - b.y); 
} 
+2

... ale PO już określił, że wie, jak sami je wdrożyć. –

+2

nie potrzebujesz "abs" na odległość Manhattanu? – none

+2

Uważam, że odległość Manhattan jest nadal błędna, zamiast tego powinna to być 'd = | (x2-x1) | + | (y2-y1) |'. – none

1

Nie za bardzo.

Odległość 2D jest funkcją matematyczną, a jeśli przyjrzymy się funkcjom matematycznym dostępnym nam w C/C++, stwierdzimy, że operują one na liczbach.

Ale to nie jest specyficzne: w rzeczywistości stwierdzamy, że funkcje mają różne nazwy (w języku C) lub są przeciążone (w C++), aby działać na różnych typach (int, float, double, & c.) Liczb . Albo to, albo casting jest wykonywany.

Na szczęście istnieją ograniczone typy liczb, więc warto mieć ogólne biblioteki, aby robić tego rodzaju rzeczy.

Teraz możemy skonstruować funkcję odległości 2D w taki sam sposób, w jaki konstruujemy funkcje matematyczne? Od razu zobaczysz, że jest to trudniejsze, ponieważ istnieje wiele sposobów na przedstawienie punktów. Na przykład, kartezjański vs. radialny, x-y vs. i-j, podwójny vs. float vs. int. Nasza ogólna odległość 2D musiałaby pokryć wszystkie te możliwości.

Większość bibliotek, które mają funkcję odległości 2D, będzie mieć towarzyszące struktury punktów w celu zmniejszenia liczby możliwości.

Istnieje jednak co najmniej jedna struktura danych, która jest zaimplementowana, dzięki czemu można zapisać punkt i użyć go do znalezienia odległości 2D przy użyciu standardowych bibliotek: liczby zespolone!

// norm example 
#include <iostream> 
#include <complex> 
using namespace std; 

int main() 
{ 
    complex<double> mycomplex (3.0,4.0); 

    cout << "The norm of " << mycomplex << " is " << norm(mycomplex) << endl; 

    return 0; 
} 

Ale to zakłada, że ​​mówimy o odległości euklidesowej. Możesz również mówić o dystansie Manhattena lub bardziej egzotycznych wskaźnikach. Zamiast starać się uwzględnić wszystkie wymienione przeze mnie możliwości, projektanci języków zdecydowali się nie wdrażać tej funkcji. (Lub jedną z wielu, wielu innych funkcji, takich jak ta, o której można rozsądnie zadać to pytanie).

EDIT: Albo można odejmować punkty i korzystać z funkcji hypot ze standardu C99. Zobacz here.

0

Boost.Geometry twierdzi, że posiada funkcje dla odległości kartezjańskiej i nie-kartezjańskiej.

Powiązane problemy