[C++] Wektory i przybliżenia


(Lol600000065) #1

witam,

iloczyn skalarny dwóch wektorów, dajmy na to 3 elementowych wygląda tak:

for(int i = 0 ; i < 3 ; ++i)

(Sawyer47) #2

Ciocia Wikipedia twierdzi, że w istocie jest to iloczyn skalarny: http://pl.wikipedia.org/wiki/Iloczyn_sk ... k.C5.82ady


(Johny) #3

Jest jeszcze skalar przez wektor

n*A[a,b]=B[a*n,b*n]


(Lol600000065) #4

OK dzięki.

A jeszcze mam takie pytanie odnośnie wektorów. Obliczanie dlugosci wektora na podstawie współrzędnej float x, y wygląda tak:

return sqrt(x*x + y*y); [/code]

:?:


(Tomek Matz) #5

Jeśli x i y to współrzędne wektora, to kod powyżej jest poprawny. Powinieneś zainwestować w tablice matematyczne :slight_smile:


(Marcin E Pc) #6

Tak dokładnie, w kartezjański układzie współrzędnych tak jest. Ogólnie to jest wzór, że długość jest równa pierwiastkowi sumy kwadratów współrzędnych.

Pozdrawiam


(Lol600000065) #7

A można potem taki wynik tej funkcji sqrt porównywać z innymi wynikami (pierwiastkami) :?: (Muszę sprawdzić czy da się zbudować trójkąt z 3 odcinków).


(Tomek Matz) #8

Można porównywać, ale z racji tego, że wynik funkcji sqrt jest typu zmiennoprzecinkowego, to musisz stosować przybliżenia, żeby się nie okazało, że 6 jest różne od 6 (z racji innego zapisu). Więcej info pod tym linkiem http://blogs.msdn.com/b/kirillosenkov/archive/2009/07/20/comparing-doubles-can-produce-unexpected-results.aspx. On wprawdzie opisuje informacje dla innego języka programowania, ale chodzi o przekazanie samej idei.


(Lol600000065) #9

Czyli co, używać funkcji ceil z :?:


(Tomek Matz) #10

Nie o to chodzi. Czytałeś tamten link co podałem? Tak jest taki fragment kodu if (Math.Abs(point.Y – 6) < 0.00000001). Chodzi o to, że jak dodasz sobie długości tych dwóch wektorów, i potem będziesz sumę długości tych dwóch wektorów porównywał z długością trzeciego wektora, to musisz zrobić coś podobnego. Czyli odjąć te dwie wartości i jeśli wartość bezwzględna tej różnicy będzie mniejsza od jakiejś liczby (przybliżenia, które sobie przyjmiesz) to znaczy, że te wartości są identyczne.


(Marcin E Pc) #11

Nie! Ja bym rzutował obie zmienne na doubla (aczkolwiek nie znam się na C++). Ceil zaokrągli Ci liczbę, czyli nie da porównanie poprawnego wyniku.


(Lol600000065) #12

A skąd mam wiedzieć jakie mam wziąć przybliżenia :smiley: :?:


(Tomek Matz) #13

To zależy od Ciebie jak dokładnych wyników potrzebujesz. W tym przykładzie wyżej przybliżenie wynosi 0.00000001 i w sumie takie powinno Ci wystarczyć. Jak będziesz chciał dokładniejszych wyników to dorzuć ze 2-3 razy przed 1 i już :).


(Darkvifon) #14

Przybliżenie chyba nie jest potrzebne. Gdyby to miał być trójkąt prostokątny, to tak, ale tutaj nie sprawdzamy równości tylko czy jedno jest mniejsze od drugiego.


(Lol600000065) #15

OK czyli ostatecznie trzeba czy nie trzeba robić przybliżeń przy takim moim warunku :?:

if(a < b + c && b < a + c && c < a + b)[/code]

(Darkvifon) #16

Moim zdaniem nie trzeba, chyba że nastąpi przypadek graniczny, co jest dość mało prawdopodobne. Dodam, że jeśli ustalisz, który bok jest najdłuższy, musisz sprawdzić tylko jedną nierówność.


(Tomek Matz) #17

Fakt, masz rację.


(Lol600000065) #18

OK dzięki wam za pomoc :slight_smile:

To prawdopodobnie zajmie mniej więcej tyle samo (może trochę mniej) co sprawdzanie tych trzech kombinacji więc sobie już to podaruję :slight_smile:


(Darkvifon) #19

E tam, std::sort się z tym szybko uwinie.

Rzucasz to do tablicy trzyelementowej i robisz

std::sort(tablica,tablica+3)

(Ryan) #20

Warunkiem koniecznym jest spełnienie nierówności trójkąta.

Jeśli natomiast nie możesz obracać wektorów, zbudują one trójkąt wyłącznie gdy ich suma jest równa zero i żaden z nich nie jest wektorem zerowym. Problem będziesz miał z tym, że operacje na floatach obarczone są błędem (który nie jest stały) i będziesz miał niepoprawne wyniki. Proponowane wcześniej rzutowanie i używanie double to tylko desperacka próba ukrycia problemu, który wciąż będzie istniał.