2013-03-08 14 views
7

Prawdopodobnie nie jest to odpowiednie miejsce, aby opublikować to ogłoszenie, ale nie wiem, gdzie go opublikować.Ogólna formuła obliczania odległości równych spacerów 3D

Mam 5 linii (d1 -> d5) równo rozmieszczonych od siebie w perspektywie 3d, mam wartości (a) kątowe, (d1) i (b5). Muszę obliczyć (b2, b3, b4, d2, d3, d4, d5) z jquery.

enter image description here

mogę obliczyć D5 z:

d5 = d1 - (b5 * Math.tan(a)) 

ale nie mam pojęcia jak obliczyć B2, B3 i B4. (d1 jest podzielony na 4 identyczne segmenty) każda pomoc byłaby doceniana.

+0

To może być http://math.stackexchange.com że chcesz. +1 dla zdjęcia mimo to. – Popnoodles

+0

Po pierwsze - to pytanie jest niesamowite. Po drugie - @popnoodles jest prawdopodobnie poprawny. Po trzecie - czy szukasz wartości długości dla każdego segmentu linii? –

+0

@popnoodles: dzięki, opublikuję tam teraz – razzak

Odpowiedz

2

To, czego szukasz, to skala rzutowa. Najprościej zrobić to obliczeniowo, to użyć homogenicznych współrzędnych, wziąć prostokąt (jak ten na pierwszym obrazku poniżej), na którym V jest "nieskończenie daleko na prawo" i znaleźć transformację rzutową, która odwzorowuje ten prostokąt na trapez w drugie zdjęcie. Wierzchołki prostokąta to (0 | 0), (0 | d1), (b5 | d1), (b5 | 0), a odpowiednie wierzchołki trapezu to (0 | 0), (0 | d1), (b5 | d5), (b5 | 0).

Illustration of a projective transformation for obtaining a projective scale

Ponieważ są to cztery punkty, z których żadne trzy nie są współliniowe, możemy znaleźć unikalną matrycę (do skalowania) M dla tej transformacji. Po kilku matematyki, okazuje się, że ta matryca jest:

[d1*b5,0,0] 
[0,b5*d5,0] 
[d1-d5,0,b5*d5] 

Jeśli chcesz znaleźć B3 koordynuje i D3, na przykład, można pomnożyć macierz jednorodnych współrzędnych punktu w środku linii tzn. wektor (0,5 * b5, d1,1)^T i otrzymujesz homogeniczne współrzędne punktu (b3 | d3), które można przekształcić na współrzędne euklidesowe przez dehomogenizację, tj. dzieląc pierwsze dwa składniki przez trzeci.

Ogólnie, jeśli masz dwa punkty (b1 | d1) i (bn | dn) i chcesz znać współrzędne n-2 w równych odległościach pomiędzy nimi na skali rzutowej takiej jak ta, możesz obliczyć współrzędne bi i di jako takiego (w przypadku, n byłoby 5, oczywiście):

let M := matrix [[d1*bn, 0, 0], [0, bn*dn, 0], [d1-dn, 0, bn*dn]] 
let v := ((i-1)/(n-1)*bn, d1, 1) 
let (x,y,z) := M*v 
let bi := x/z and di := y/z 

jak widać, jest to prosty algorytm do obliczania współrzędnych tych projectively równoodległych punktach, a to generalizowaniu ładnie arbitralny liczba punktów.

Jeśli wolisz mieć zamkniętą formułę, można obliczyć bi oraz di bezpośrednio jako:

let bi := (bn*d1*(i-1))/(dn*n+(d1-dn)*i-d1) 
let di := d1*dn*(n-1)/(dn*n+(d1-dn)*i-d1) 
+0

dzięki za twoją odpowiedź, ale jak mogę to wykorzystać w jquery ?! – razzak

+0

Bez obrazy, ale JavaScript jest językiem prosto z piekła i nie zamierzam go dotykać. Jednak nie widzę problemu - wystarczy napisać kod JavaScript dla ostatnich dwóch wierszy kodu, który napisałem, co nie powinno być trudne w żadnym języku programowania. Może coś jak http://pastebin.com/T3yuyTW3. b [1], b [5], d [1], d [5] muszą zawierać odpowiednie wartości na początku programu, pozostałe wpisy b i d zostaną następnie wypełnione w pętli. (Nie mam pojęcia, czy jest to poprawny JavaScript, ale powinien to być jego sedno) –

+0

zakładając, że dwie formuły są poprawne 'let bi: = (bn * d1 * (i-1))/(dn * n + (d1-dn) * i-d1) niech di: = d1 * dn * (n-1)/(dn * n + (d1-dn) * i-d1) ' jeśli zmieniam kąt (a) to nie wydaje się mieć żadnego wpływu na formułę! – razzak

0

enter image description here

Najpierw musimy obliczyć długość przyległego boku całego trójkąta d1 ->v ->c jest (lewy pionowy bok od niego):

tan(Θ) = opposite/adjacent 
opposite * tan(Θ) = adjacent 
adjacent = opposite * tan(Θ) 
adjacent = d1 * tan(a) 

Następną rzeczą, musimy to wiedzieć, ile nad ziemią każdy wiersz z v jest, gdy robi się do linii d1. Biorąc pod uwagę, że zmienna s jest taka sama dla wszystkich działów i zakładając N podzielenie segmentów (w tym przypadku 3), nasz licznik jest i, że zaczyna się od 1 i przechodzi do N:

opposite(i) = i * (d1/N) 

teraz musimy kąta linii z przeciwko do każdego markera ów sprawia:

tan(Θi) = opposite/adjacent 
Θi = arctan(opposite/adjacent) 
Θi = arctan(opposite(i)/adjacent) 
Θi = arctan((i * (d1/N))/(d1 * tan(a))) 

Przy użyciu geometrii/trig możemy powiedzieć, że kąt przechodzenia od d1 przez punkt c do góry d5 wynosi (90 ° - a).Będziemy nazywać ten kąt a „

a' = 90° - a 

twierdzenie sinusów mówi nam, że:

A'/sin(a') = opposite(i)/sin(b') 

więc teraz możemy rozwiązać na A”, ponieważ potrzebujemy pomocy z coraz wymiary pomarańczowego kwadratu :

A' = (opposite(i) * sin (a'))/sin(b') 

od b” = ( + Θi) to zamienia się:

A' = (opposite(i) * sin (90° - a))/sin(a + Θi) 

samo zastosowano ale rozwiązywanie godz w pomarańczowym trójkąta (patrz zdjęcie):

h/sin(90°-Θi) = A'/sin(90°) 
h = (A' * sin(90°-Θi))/sin(90°)  
b2 = h 

Kładzenie to wszystko razem (oby bez kopiuj/wklej błędy z mojej strony) i bez uproszczeń:

b2 = ((((i * (d1/N)) * sin (90° - a))/sin(a + Θi)) * sin(90° - arctan((i * (d1/N))/(d1 * tan(a)))))/sin(90°)  

Teraz spłucz/powtórz dla każdej wartości i i zamieni się w kod (zrobiłbym to, ale jestem zbyt zmęczony) :)

+0

'tan (Θ) = naprzeciwko/sąsiednie - -> sąsiadujący = przeciwny/tan (0) 'prawda? – razzak

+0

yup :) Jeśli chodzi o ", to dlatego, że trójkąt z punktów b5-> d5-> c ma w sumie 180 stopni w środku. jeden z nich to 90, a drugi to a, a więc pozostały kąt to 180-90-a = 90-a chociaż możesz mieć rację, że jest zależny od b5 –

Powiązane problemy