Odległość między obiektami na planszy jednym równaniem

1

Zastanawiałem się nad tym, pewnie proste do dowiedzenia, czy tak się da, czy nie, ale jednak nie umiem znaleźć rozwiązania. Piszę to w Javascripcie, ale w sumie problem jest algorytmiczny.

Mam planszę, na niej dwa obiekty, każdy to okrąg, mogą mieć różne promienie. Ostatecznie ostatnie wymaganie mogę zmienić, ale chciałbym, żeby mogłby mieć różne.

Chciałbym policzyć między nimi odległość (w pikselach), powiedzmy w pionie, tylko chodzi mi o to, żeby zmienna, która będzie ją przechowywać, była liczona w jednym miejscu (===jednym równaniem) – a nie na przykład różnie przypisywana w zależności od warunku if.

Do tej pory udało mi się osiągnąć, by odległość między "położeniami" obiektów (czyli ich wartościami top) była liczona jednym równaniem, i tak to wygląda:

(pseudokod)

// x1 – obiekt nr 1 
// x2 – obiekt nr 2
// top() – położenie obiektu na planszy (jego górna granica)
odległość_położeń := | top(x1) - top(x2) | // niezaleznie czy obiekt x1 jest nad obiektem x2, czy pod, wykorzystane jest jedno rownanie

Ale żeby obliczyć tę właściwą odległość między obiektami (czyli uwzględniając ich wysokość), jak na razie muszę dawać warunek:

(pseudokod)
// height() – wysokość obiektu
if ( top(x1) < top(x2) ) {
    odległość := | top(x1) - ( top(x2) + height(x2) ) |
} else {
    odległość := | ( top(x1) + height(x1) ) - top(x2) |
}

UPDATE: Poprawiłem błędy w ostatnich równaniach.

3

Geometrię w podstawówce miałeś? Z racji, że to są okręgi, to dystans między nimi wynosi:

d(C_1, C_2) - (r_1 + r_2)

Gdzie para (C_i, r_i) to odpowiednio środek okręgu oraz jego promień. A funkcja d(A, B) to zadana metryka, w tym przypadku można ją łatwo przybliżyć metryką euklidesową, więc masz d(A, B) = \sqrt{(x_A - x_B)^2 + (y_A - y_B)^2}

0

Ok, to rozwiązanie jest w porządku, dzięki, @hauleth, że przypomniałeś mi, jak to powinienem zrobić zgodnie ze sztuką. :) Dzięki temu dorobiłem w każdym obiekcie własności zwracające współrzędne x oraz y, co ułatwiło sprawdzanie.

I to jest dla okręgów. A jak mogłoby wyglądać obliczanie odległości na przykład dla dowolnych elips? Chodzi mi o to, żeby nie było założenia, że po skosie jest taka sama odległość jak w pionie i w poziomie. W szczególności chodzi mi o pokazanie różnic między tymi wzorami.

Pewnie mógłbym to znaleźć w internecie, ale wolę oszczędzić sobie godziny szukania (albo i więcej), jeśli ktoś to już wie.

1

@Silv, dla elips lepiej użyć czegoś w stylu bounding box/bounding circle albo na pałe fragment raymarchingu zrobić (liczysz distance field i sprawdzasz w paru punktach na krawędzi drugiego kształtu). Jeśli musisz mieć dokładnie/analitycznie to kartka długopis i liczysz. Jeśli to jest do gry to prawie zawsze łatwiej, szybciej i lepiej to zrobić kilkoma kołami przybliżającymi kształt Twojej figury i sprawdzić minimum dla każdej z par kół (da się przyspieszyć jeśli Ci się chce, ale najpierw zobacz czy musisz)

Dla elipsy distance field możesz policzyć uproszczoną wersją tego wzoru (to jest dla 3d elispoid):

float sdEllipsoid( in vec3 p, in vec3 r )
{
    return (length( p/r ) - 1.0) * min(min(r.x,r.y),r.z);
}

tutaj masz rożne inne figury: http://iquilezles.org/www/articles/distfunctions/distfunctions.htm (zauważ to jest dystans od punktu)

0

@krwq: to brzmi ciekawie! Tylko tak:

  • Bryłę brzegową rozważę; aczkolwiek planuję umożliwić tworzenie obiektów znacznie się różniących, także nie-elips (choć zawsze symetrycznych), więc nie sądzę, by była ona ostatecznym kształtem mojego rozwiązania.
  • "Jeśli musisz mieć dokładnie/analitycznie to kartka długopis i liczysz." – no tak, ale jak liczę?
  • "Jeśli to jest do gry to prawie zawsze łatwiej, szybciej i lepiej to zrobić kilkoma kołami przybliżającymi kształt Twojej figury i sprawdzić minimum dla każdej z par kół (da się przyspieszyć jeśli Ci się chce, ale najpierw zobacz czy musisz)" – tak, to taka jakby gra wyjdzie; wolałbym ograniczyć obliczenia w pętli, w której gra działa (to Javascript) – jeszcze zresztą pewnie założę tu wątek o tym, jak ją przyspieszyć – choć jeśli już, to zrobię coś takiego, że obliczę dwa koła, jedno na zewnątrz elpisy, a drugie wewnątrz, i obliczę ich średni promień. Choć na razie brzmi mi to bardzo jak "działa, ale obiekty odbijają się kilka pikseli od siebie".

UPDATE: O, jeszcze wzór i link doszły. :) Zobaczę i zaktualizuję ten post.

0

Choć na razie brzmi mi to bardzo jak "działa, ale obiekty odbijają się kilka pikseli od siebie".

Użytkownicy preferują płynnie działającą grę niż dokładne kolizje. Nikt nie zauważy, że coś odbija się o piksel za daleko.

Distance field można użyć dla dowolnych kształtów i powinno działać dość szybko jeśli masz tylko kilka obiektów

1

Użytkownicy preferują płynnie działającą grę niż dokładne kolizje. Nikt nie zauważy, że coś odbija się o piksel za daleko.

No mam taką nadzieję, że będę mógł wpleść pewne uproszczenia. Aczkolwiek i tak nie planuję zrobić z tego gry "do użytku", raczej to dla mojej nauki Javascriptu.

Distance field można użyć dla dowolnych kształtów i powinno działać dość szybko jeśli masz tylko kilka obiektów

I także jeśli chodzi o wcześniejszy wzór – nie bardzo go rozumiem i wolałbym nie wchodzić w 3D (na razie? ;) ), ale myślę, że jeśli nie znajdę nic stricte do 2D, to coś takiego spróbuję wykorzystać.


UPDATE: A o distance field sobie poczytam.

0

Przyszło mi coś do głowy. To takie bardzo home-made, ale a nuż mam rację? Czy przypadkiem na poniższym rysunku wyróżnione dwa trójkąty nie mają równych proporcji boków? Z doświadczenia wiem, że czasem tak nie jest, ale wolę zapytać. ;)

Zrzut ekranu z 2018-04-21 02-17-12.png


UPDATE: Przybliżone obliczenia w LibreOffice Impress mówią, że jednak nie, że proporcje różnią się. Trzeba chyba wrócić do równań, ech...

0
Silv napisał(a):

Przyszło mi coś do głowy. To takie bardzo home-made, ale a nuż mam rację? Czy przypadkiem na poniższym rysunku wyróżnione dwa trójkąty nie mają równych proporcji boków? Z doświadczenia wiem, że czasem tak nie jest, ale wolę zapytać. ;)

Jeśli linie pionowe są pionowe a poziome poziome, :) to trójkąty są podobne, więc mają równe proporcje.


UPDATE: Przybliżone obliczenia w LibreOffice Impress mówią, że jednak nie, że proporcje różnią się. Trzeba chyba wrócić do równań, ech...

Robisz obliczenia w LibreOffice IMPRESS?????

0

Robisz obliczenia w LibreOffice IMPRESS?????

W zasadzie nie "obliczam", tylko "udowadniam numerycznie" na potrzeby domowe. ;)

Jeśli linie pionowe są pionowe a poziome poziome, :) to trójkąty są podobne, więc mają równe proporcje.

Na pewno? Podasz jakieś równania, z których to wynika?

1 użytkowników online, w tym zalogowanych: 0, gości: 1