Autor Wątek: wykrywanie i odp. kolizji w kwadracie  (Przeczytany 3008 razy)

Offline cruelmatt

  • Użytkownik

# Grudzień 06, 2008, 10:29:00
witam,
chcialbym sie spytac jak mozna wykryc i odpowiedziec na kolizje rysowanych kwadratow jesli mam 2 kwadraty, ktorym sa przypisane zmienne na wszystkie wierzcholki(x1,y1,x2,y2,x3,y3,x4,y4) ??

Matt.

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline compawo

  • Użytkownik

# Grudzień 06, 2008, 11:55:36
Kolizje na prostokątach (w szczególności kwadratach) testujesz sprawdzając, czy jeden z wierzchołków pierwszego znajduje się w polu drugiego prostokąta.

@2xdown udowodniono wadę tej techniki
« Ostatnia zmiana: Grudzień 06, 2008, 13:17:38 wysłana przez compawo »

Offline cruelmatt

  • Użytkownik

# Grudzień 06, 2008, 12:10:23
wiem, ale czy moglbym dostac jakis przykladowy kod na taka kolizje?

Matt.

Offline skoti

  • Użytkownik

# Grudzień 06, 2008, 12:43:43
Kolizje na prostokątach (w szczególności kwadratach) testujesz sprawdzając, czy jeden z wierzchołków pierwszego znajduje się w polu drugiego prostokąta.

Offline skalniak

  • Użytkownik
    • Home page

# Grudzień 06, 2008, 12:56:14
Cześć możesz zrobić to na wiele sposobów - dwa przytoczę na poczekaniu. Pierwszy to rozpatrywać wiele przypadków - wszystkie które mogą zaistnieć czyli:
1) czy któryś z pkt. jest w polu drugiego itp
2) osobno przypadek z rys. wyżej

Drugim sposobem jest sprawdzanie czy proste się przecinają i czy ma to miejsce na odcinkach łączących wierzchołki.

--
skalniak

Do poczytania:
PS. na forum znalazłem także wątek, który może Ci pomóc: http://forum.warsztat.gd/index.php/topic,1420.0.html
PS2: http://wiki.warsztat.gd/Kolizje_mi%C4%99dzy_prostok%C4%85tami_na_p%C5%82aszczy%C5%BAnie
« Ostatnia zmiana: Grudzień 06, 2008, 13:04:37 wysłana przez skalniak »

Offline counterClockWise

  • Użytkownik

# Grudzień 06, 2008, 14:16:07
witam,
chcialbym sie spytac jak mozna wykryc i odpowiedziec na kolizje rysowanych kwadratow jesli mam 2 kwadraty, ktorym sa przypisane zmienne na wszystkie wierzcholki(x1,y1,x2,y2,x3,y3,x4,y4) ??

Matt.

Ja proponuję tak:

1. Test czy kolidują kule opisane - jeden prosty warunek na promienie. NIE: nie ma kolizji. TAK: idziemy dalej.
2. Test czy kolidują kule wpisane - TAK: jest kolizja. NIE: idziemy dalej.
3. Test na przecięcie (odcinek-odcinek) dla każdego boku kwadrata. Raptem 16 testów, które odpalane będą rzadko, bo wcześniej testujemy kulami :)

wydaje mi się, że to najlepsze i optymalne.



Offline Reg

  • Administrator
    • Adam Sawicki - Home Page

# Grudzień 06, 2008, 14:54:02
Jeśli dane są dwa prostokąty r1 i r2, a każdy ma określone mniejsze i większe współrzędne jako odpowiednio left, right, top, bottom, to funkcja która sprawdza czy dwa prostokąty mają część wspólną (kolidują) wygląda tak:

inline bool RectToRect(const RECTF &r1, const RECTF &r2)
{
return
(r1.left <= r2.right) &&
(r1.right >= r2.left) &&
(r1.top <= r2.bottom) &&
(r1.bottom >= r2.top);
}

Offline Spider100

  • Moderator
    • Strona domowa

# Grudzień 06, 2008, 14:57:45
Tylko SAT.. to zaledwie 8 iloczynów skalarnych i parę porównań i wiemy czy cokolwiek się nakłada.

Offline cruelmatt

  • Użytkownik

# Grudzień 06, 2008, 15:07:27
no wlasnie w tym problem jak uzyskac prosta skoro rysuje kwadrat samymi wierzcholkami? Mam odejmowac od siebie pozycje wierzcholkow aby uzyskac dlugosc boku?

Offline smajler

  • Użytkownik

# Grudzień 06, 2008, 15:14:02
ktos keidys dal mi tu na forum funkcje do testowania kolizji prostokat prostokat:
struct OBIEKT{
float x,y,x2,y2;
};

bool Kolizja(OBIEKT kto,OBIEKT z_kim)                 //funkcja do sprawdzania kolizjii
{
     if((kto.x>z_kim.x2)||(kto.x2<z_kim.x)||(kto.y>z_kim.y2)||(kto.y2<z_kim.y)) return false;
     return true;
}

Jeszcze raz podziekuje temu komus:P wtedy uratowal mi zycie ;)
« Ostatnia zmiana: Grudzień 06, 2008, 15:15:57 wysłana przez smajler »

Offline cruelmatt

  • Użytkownik

# Grudzień 06, 2008, 15:22:42
ale ja uzywam do rysowania prostokatow : x1 y1, x2 y2, x3 y3, x4 y4 czyli wspolrzedne kazdego wierzcholka.

poopa

  • Gość
# Grudzień 06, 2008, 16:07:52
No właśnie panowie... To nie muszą być prostokąty równoległe do siebie przecież.

Generalnie do opisu takiego prostokąta nie potrzebujesz aż 4 punktów... wystarczą 3,a  nawet 2 i zwrot ale co tam.

Polcam to samo co Spider... nic innego nie wymyślisz, bo nie warto nawet.

Mniej więcej coś takiego(z głowy):
struct Rect
{
float3 a,b,c,d;
};
/////////////////////
Rect rectA,rectB;
float3 dir=rectA.b-rectA.a;
float length=dir.Length();
float3 point=rectB.a-rectA.a;
float result=Float3::Dot(&point,&dir);
if (result<length)
  if(result>=0.f)
  {
    point=rectB.b-rectA.a;
    result=Float3::Dot(&point,&dir);
    if(result<length)
      if(result>=0.f)
      {
      //itd. itp. ... jak to rozpiszesz to sobie ładnie popatrz i skróć gdzie się da.
      }
  }

Offline cruelmatt

  • Użytkownik

# Grudzień 06, 2008, 16:16:31
nie rozumiem, jestem poczatkujacy i poprostu chcialem sobie napisac mini-ponga, a tak wyglada u mnie rysowanie kwadratu:

glBegin(GL_QUADS);

glTexCoord2f(0.0f, 0.0f);
glVertex3f(player.x1, player.y1, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(player.x2, player.y2, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(player.x3, player.y3, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(player.x4, player.y4, 0.0f);

glEnd();

Offline Zielony

  • Użytkownik
    • Ghurund Engine

# Grudzień 06, 2008, 16:34:57
No właśnie panowie... To nie muszą być prostokąty równoległe do siebie przecież.
[...]
Polcam to samo co Spider... nic innego nie wymyślisz, bo nie warto nawet.

Oj zaraz nie wymyślisz. Jest bardzo fajna metoda badania z użyciem sumy Minkowskiego, która sprowadza kolizję dwóch n-wymiarowych brył do kolizji punktu (0,0,...,0) z bryłą. Co prawda daleko zbyt skomplikowana dla tego przypadku, ale jest ;]

Offline counterClockWise

  • Użytkownik

# Grudzień 06, 2008, 19:48:06
Jeśli dane są dwa prostokąty r1 i r2, a każdy ma określone mniejsze i większe współrzędne jako odpowiednio left, right, top, bottom, to funkcja która sprawdza czy dwa prostokąty mają część wspólną (kolidują) wygląda tak:

inline bool RectToRect(const RECTF &r1, const RECTF &r2)
{
return
(r1.left <= r2.right) &&
(r1.right >= r2.left) &&
(r1.top <= r2.bottom) &&
(r1.bottom >= r2.top);
}

A jak prostokąty się poruszają i obracają? Za każdym razem nazywasz współrzędne na nowo?
A jak np. prostokąt przypomina symbol Karo - stoi na jednym z wierzchołków (przekątna pionowo), to co jest wtedy left, right, top, bottom?



Jeżeli left i right będą takie jakby ten prostokąt stał na podstawie to mam kontrprzykład,pokazujący że Twoja metoda niestety nie działa :)
Moja metoda działa dla dowolnej transformacji afinicznej prostokąta.
« Ostatnia zmiana: Grudzień 06, 2008, 19:51:05 wysłana przez counterClockWise »