Detekce kolize – Pascal – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Detekce kolize – Pascal – Fórum – Programujte.comDetekce kolize – Pascal – Fórum – Programujte.com

 

29. 4. 2007   #1
-
0
-

Ahoj, hraju si v pascalu s grafikou a potřebuju poradit s detekcí kolize. Zatím mají všechny objekty, i ty kruhové, pro detekce kolize model obdélníka, a občas to ne úplně lícuje. Tak se chci zeptat, jestli se dá nějak zjišťovat kolize s kruhem?

Nahlásit jako SPAM
IP: ...–
Tomass
~ Anonymní uživatel
20 příspěvků
29. 4. 2007   #2
-
0
-

To nieje az take tazke. Povedzme ze mas 2 kruhy zo stredmy S1, S2 a polomermi r1, r1.
S1(x1, y1)
S2(x2, y2)
Potom kolizia nastane ked |S1S2|<=(r1+r2) , z toho :
sqr((x1-x2)^2+(y1-y2)^2)<=(r1+r2)

Nahlásit jako SPAM
IP: ...–
29. 4. 2007   #3
-
0
-

To Tomass: Jo, Pythagorova věta a poloměry... vidíš, to mě ani nenapadlo... díky moc. Zmíním tě v Credits :)
A jak by to vypadalo pro kolizi kruhu a obdélníka? (sorry, jsem dneska nějakej natvrdlej...)
//nebo obecně kruhu a bodu?
///už jsem na to asi přišel... prostě jako že poloměr 0 :D

Nahlásit jako SPAM
IP: ...–
29. 4. 2007   #4
-
0
-

Tak jsem zkusil kolizi dvou kruhů (taky se mi hodí) jak jsi napsal, ale hází mi to Arithmetic overflow... co je špatně?

  repeat

{saucer}
if sqrt(sqr(h-mx[z])+sqr(v-my[z]))<(size+25) then sracka:=true;
inc(z);
until sracka or (z>cycles);

h a v jsou souřadnice středu 'létajícího talíře', do kterého nesmí nic narazit, mx[*] a my[*] jsou souř. středů kruhů, u kterých se zjišťuje jestli do něj narazily... ty jsou všechny stejné a jejich poloměr je size. 25 je poloměr 'létajícího talíře'.

Nahlásit jako SPAM
IP: ...–
Laaca
~ Anonymní uživatel
225 příspěvků
29. 4. 2007   #5
-
0
-

Napiš nám jak vypadají deklarace proměnných, ať víme, jakého jsou typu.

Nahlásit jako SPAM
IP: ...–
29. 4. 2007   #6
-
0
-

To Laaca: Asi vím, kam tím míříš a napadlo mě to taky... všichni zúčastnění jsou integer, jenom z a size jsou byte a sracka je samozřejmě boolean.

Nahlásit jako SPAM
IP: ...–
30. 4. 2007   #7
-
0
-

Ten Tomassův postup jsem zkoušel v samostatném programu a očividně funguje tak jak má, ale jakmile to zabuduju kamkoliv do svého programu, vyhodí to ten overflow... nevím, co tomu může vadit...

Nahlásit jako SPAM
IP: ...–
30. 4. 2007   #8
-
0
-

Tak nakonec pomohlo vyměnit integer u mx a my za longint nebo word... ale to mi teda někdo vysvětlete, proč...

Nahlásit jako SPAM
IP: ...–
Laaca
~ Anonymní uživatel
225 příspěvků
1. 5. 2007   #9
-
0
-

Protože při mocnění došlo k překročení rozsahu integeru. Uvědom si, že "sqr(h-mx[z]" přeteče, když H je třeba 0 a mx[z]=300
0-300=-300 a -300 na druhou = 90000, což je podstatně víc, než obsáhne integer.

Nahlásit jako SPAM
IP: ...–
1. 5. 2007   #10
-
0
-

No já jsem nepočítal s tím že on ty výpočty bude dělat v těch proměnných...

Nahlásit jako SPAM
IP: ...–
Mircosoft+1
Věrný člen
2. 5. 2007   #11
-
0
-

Když se počítá hodnota nějakého výrazu, uloží se do dočasné proměnné, která je toho "největšího" typu ze všech proměnných a konstant použitých ve výrazu. Když mám třeba sqr((i*l) div b), kde i je integer, l longint a b byte, tak výsledná hodnota, která se předá jako parametr sqr, bude longint. Kdybych tam měl místo longintu integer, byl by výsledek taky integer.

Btw., přeteklý integer = záporné číslo. Potom pozor na odmocniny.

Nahlásit jako SPAM
IP: ...–
Chceš-li lepší odpověď, polož lepší otázku.
Moje stránka.
Laaca
~ Anonymní uživatel
225 příspěvků
2. 5. 2007   #12
-
0
-

Pravda. S Overflow checking ON nastane chyba už při tom mocnění a s OFF teprve při odmocňování :-)

Nahlásit jako SPAM
IP: ...–
12. 5. 2007   #13
-
0
-

Nevíte někdo, jak udělat kolizi obdélníka a kruhu?

Nahlásit jako SPAM
IP: ...–
Mircosoft+1
Věrný člen
15. 5. 2007   #14
-
0
-

To už je trošku složitější, budeš muset řešit několik případů.
Předpokládám, že máš kruh o středu kx,ky a poloměru r a obdélník s levým horním rohem lhx,lhy a pravým dolním pdx,pdy.

1) (kx>=lhx)and(kx<=pdx): pak je kruh buď nad obdélníkem nebo pod ním a nebo aspoň částečně v něm. If (ky+r>=lhy)or(ky-r<=pdy) then kolize ano.
2) (ky>=lhy)and(ky<=pdy): je buď vlevo nebo vpravo nebo v něm - to samé pro vodorovný směr: If (kx+r>=lhx)or(kx-r<=pdx) then kolize ano.
3) ostatní případy, tj. střed kruhu je někde šikmo, ale není ani nad, ani pod, ani vodorovně stranou od obdélníka. Potom: if (vzdalenost(kx,ky,lhx,lhy)<=r)or(vzdalenost(kx,ky,lhx,pdy)<=r)or(vzdalenost(kx,ky,pdx,lhy)<=r)or(vzdalenost(kx,ky,pdx,pdy)<=r) then kolize ano (prostě testuju, jestli kružnice přesahuje nějaký roh). Funkce Vzdalenost(a,b,c,d) počítá vzdálenost bodu a,b od c,d, to už určitě zvládneš.

Nahlásit jako SPAM
IP: ...–
Chceš-li lepší odpověď, polož lepší otázku.
Moje stránka.
15. 5. 2007   #15
-
0
-

Dík, nemusels to psát takhle do detailů. Stačilo říct, že přímo to nejde, ale musí se přes body. Ale v normální analytický geometrii tohle jde docela jednoduše: když mám rovnici kružnice a parametrické rovnice úsečky, řeší se to jako soustava dvou rovnic nebo v tomhle případě by to šlo i snad sloučit do jedný rovnice... zamyslel bych se nad tím, ale momentálně mě trápí úplně jiný problém, a pokud ho nevyřeším, tak je mi detekce kolize k ničemu... snad nebude vadit když se zeptám tady.

    for b:=0 to e do begin

if (mx+25>h) and (mx-25<h) then begin {disruptors}
dx:=mx;
dy:=my;
disruptor:=true;
end;
(...)
for c:=0 to e do if disruptor[c] then begin {disruptory - grafika}
setcolor(0);
line(dx[c],dy[c],dx[c],dy[c]-5);
line(dx[c]-1,dy[c]-1,dx[c]+1,dy[c]-1);
line(dx[c]-1,dy[c]-3,dx[c]+1,dy[c]-3);
dy[c]:=dy[c]+2;
setcolor(10);
line(dx[c],dy[c],dx[c],dy[c]-5);
line(dx[c]-1,dy[c]-1,dx[c]+1,dy[c]-1);
line(dx[c]-1,dy[c]-3,dx[c]+1,dy[c]-3);
end;

mx[*],my[*]: tentokrát souřadnice nepřátelských lodí
h,v: souřadnice lodi hráče (Enterprise)
dx[*],dy[*]: souřadnice projektilu z disruptoru
disruptor[*]: boolean array, určuje, jestli ta či ona loď už vystřelila nebo ne

Co to má dělat:
Podmínkou pro vystřelení je, aby se loď nacházela v takovém rozsahu x souřadnic, aby trefila Enterprise, tedy h plus mínus 25. Pokud je podmínka splněna, do disruptor se uloží true a za souřadnice projektilu se zkopírují souřadnice lodi (jak jinak). Dále program zjišťuje v cyklu, střely od jakých lodí na obrazovce jsou a od jakých ne, a podle toho je vykresluje - smaže, pak posune (projektil je 2x rychlejší než loď) a zase nakreslí.

Co to dělá:
Když je splněna původní podmínka, před nepřátelskou lodí se nakreslí projektil, ale zůstane tam přilepený a začne se pohybovat tak jak má až za několik sekund. Nechápu proč. Taky se ty projektily během letu občas zaseknou a už se nesmažou... prostě je to nějaký divný.

Vidíte v tom kódu někde chybu nebo je tohle prostě nad možnosti BGI?

Nahlásit jako SPAM
IP: ...–
Mircosoft+1
Věrný člen
16. 5. 2007   #16
-
0
-

Začátek:
if (mx+25>h) and (mx-25<h) then...
bych přepsal na:
if (abs(mx-h)<25) and not disruptors then...
První část je jen zjednodušená podmínka "když xová vzdálenost je menší než 25", druhá testuje, jestli už náhodou příslušný klingon nevystřelil. Tady asi byla ta chyba, protože když to neotestuješ, tak se bude tatáž střela vytvářet v každém cyklu znova a tak dlouho, dokud s Enterprise neodletíš mimo ten rádius 25 pixelů.

(Edit: teď koukám, že ta původní podmínka byla navíc špatně. Měla by být if (mx+25<h) and (mx-25>h) then...)

Zbytek je asi OK. Jenom bych ještě doporučil vyřešit kreslení střel procedurou, kterou předáš jako parametry souřadnice a barvu. Mazání pak vyřešíš voláním KresliDisruptor(x,y,0) a kreslení KresliDisruptor(x,y,10) - bude to pohodlnější.

Nahlásit jako SPAM
IP: ...–
Chceš-li lepší odpověď, polož lepší otázku.
Moje stránka.
16. 5. 2007   #17
-
0
-

>Mircosoft: Máš pravdu, s absolutní hodnotou je to lepší. Jo, testovat tu podmínku, to je proč to nefunguje... díky moc - jsem prostě potřeboval aby se na to podíval někdo jinej, protože já v tom vlastní chyby nevidím.

Kreslení disruptoru bych procedurou nedělal, jsou to tři řádky kódu, takže to bordel nedělá.

Nahlásit jako SPAM
IP: ...–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 1 host

Podobná vlákna

Kolize — založil milanmichal

Kolize — založil Dusan

Kolize — založil "Andrje"

Kolize kodovani — založil tribalcz

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý