Hirdetés

2024. május 4., szombat

Gyorskeresés

Útvonal

Fórumok  »  Szoftverfejlesztés  »  C++ / mfc pattogó labda, help! (téma lezárva)

Hozzászólások

(#1) [Kovi]


[Kovi]
tag

Szóval kéne írnom egy progit C++ -ban ami kirak egy ablakot és abban rajzol egy négyzetet, amiben egy labda pattog, úgy hogy a falról rendesen visszapattan meg minden. Meg is írtam a progit, csak ugye átdolgoztam hogy állítható legyen a kezdés helye pixelben (szal ahonnan indul a labda), illetve a szög amiben elindul a labda. És itt jön a progbléma.. Vannak bizonyos szögtartományok amiknél a labda kilép a baloldali illetve a felső kereten. 4 ilyen szögtartomány 4*60 fok szal összesen 240 fok. A maradék 120 fokban megy rendesen, de így ugye 2szer akkora az a tartomány ahol nem jó, mint ahol jó, és nem látom a megoldást. A lebda mozgását így oldottam meg:

m_vy++;
m_vx++;
m_x=m_x2+m_ex*m_vx*(cos(m_alfa*pi/180));
m_y=m_y2+m_ey*m_vy*(sin(m_alfa*pi/180));
dc.Ellipse(m_x-10,m_y-10,m_x+10,m_y+10);
if (m_y<Ys+12) {m_ey*=-1; m_y2=m_y; m_vy=1;}
if (m_x>Xs+Xh-12) {m_ex*=-1; m_x2=m_x; m_vx=1;}
if (m_y>Ys+Yh-12) {m_ey*=-1; m_y2=m_y; m_vy=1;}
if (m_x<Xs+12) {m_ex*=-1; m_x2=m_x; m_vx=1;}

Ahol m_x2 / m_y2 a kiindulási pont ahonann elindul a labda, ezeket egy edit boxból kéri be. az m_vx, és m_vy x és y irányú komponensek, tulajdonképpen csak szorzók amikkel a következő pontot számolja. m_alfa pedig a szög, de cos, sin függvények radiánban kérik ezért kell m_alfa*pi/180. m_ex, m_ey, pedig csak előjel szorzók, alapból 1 az értékük, így tulképpen ütközés után csak a mozgás valamelyik irányú komponensének előjelét fordítják. mivel csak felül és baloldalt lép ki, az 1. és az utolsó feltételben lehet a hiba csak nemtudom hogy mi. Fontos lenne, mert hétfőre le kéne adnom a progit egyetemen, szal segítsetek plíz!

Szerk: jah ami kimaradt: Ys, Xs, a négyzet bal felső sarkának koordinátái amiben pattog(na) a labda. Xh, Yh, pedig a négyzet adott irányú hosszúsága..

[Szerkesztve]

Szabadság, szerelem, Ext2 kell nekem.

(#2) Pizzafutar válasza [Kovi] (#1) üzenetére


Pizzafutar
aktív tag

Esetleg signed/unsigned problema?

(#3) [Kovi] válasza Pizzafutar (#2) üzenetére


[Kovi]
tag

Hát alapból asszem minden int -nek deklarált változót signed-nak vesz.. meg azért is furcsa lenne mert sin / cos függvények ugyan abban a tartományban vannak 31 fokra, mint pl 30-ra.. és 31 foknál még megy rendesen, 30-nál pedig már kirepül fölül.. De lehet fel tudom tölteni forrást vhova..

Szabadság, szerelem, Ext2 kell nekem.

(#4) Pizzafutar válasza [Kovi] (#3) üzenetére


Pizzafutar
aktív tag

Kuld at, megnezem

(#5) [Kovi]


[Kovi]
tag

Nah feltöltöttem extrára.. tömörítve csak 25K
[L]http://www.extra.hu/dirtyreading/labda.zip[/L]
Extra lehet sírni fog hogy kívülről nem elérhető, de adni fog egy linket és akkor onnan már le lehet szedni..

Amúgy 6.0-s MS Visual C++ os project ként van mentve ha ez számít valamit..

[Szerkesztve]

Szabadság, szerelem, Ext2 kell nekem.

(#6) Pizzafutar válasza [Kovi] (#5) üzenetére


Pizzafutar
aktív tag

nezem....

(#7) BlackWoOd válasza [Kovi] (#1) üzenetére


BlackWoOd
aktív tag

Hú, nem bonyolítottad ezt egy kicsit túl?

Elvégre négyszög alakú területen belül pattog a labda, nem is kell cos/sin függvény, csak sima függőleges és vízszintes határvizsgálat (2-2 db if), szerintem.

Elég csak azt nézned, hogy elérte-e a labda megfelelő koordinátája a határ értékeket és akkor kell mozgásirányt fordítanod...

< ..kevés az ember, sok az emberszerű lény... >

(#8) [Kovi] válasza Pizzafutar (#6) üzenetére


[Kovi]
tag

Van hozzá builder-ed, szal le tudod futtatni, vagy töltsem fel .exe-t is?

Szabadság, szerelem, Ext2 kell nekem.

(#9) [Kovi] válasza BlackWoOd (#7) üzenetére


[Kovi]
tag

Persze de az a lényeg hogy lehessen állítani kiindulási szöget, és falról is ugyan abban a szögben pattanjon vissz. És moszgáshoz meg ki kell gonolnod hogy mi az adott úthoz tartozó következő lépés, vagyis melyik az az (x,y) érték ahova tovább kell mozgatnod.. De ha a te megoldásod működik így is, akkor írd le plíz engem érdekel..

Szabadság, szerelem, Ext2 kell nekem.

(#10) Pizzafutar válasza [Kovi] (#9) üzenetére


Pizzafutar
aktív tag

Nos rajottel mar te is?
itt van a hiba: m_x=m_x2+m_ex*m_vx*(cos(m_alfa*pi/180))

(#11) Pizzafutar válasza Pizzafutar (#10) üzenetére


Pizzafutar
aktív tag

Mivel cos(61) < 0.5, ezert it mx eretke nem valtozik.
ezek utan a 4. if mindig vegrehajtodik!
lasd:
int t = m_ex*m_vx*(cos(m_alfa*pi/180));
m_x=m_x2+ t;

itt t mindig 0 marad.
Megoldas: vagy atirod a valtozokat double -ra, vagy hasznalsz valamilyen kerekitest, flor es tarsai!

(#12) [Kovi] válasza Pizzafutar (#11) üzenetére


[Kovi]
tag

én is szögfügvényekre gyanakodtam, de én előjelezés miatt, viszont ugye 30 és 31 vagy 60 és 61 fok ugyan abba a tartományba esik + / - szempontjából, mármint ha sin / cos - ukat nézzük.. de így már tényleg ok szal a kerekítés.. minnyá megpróbálom double-ra átírni..

Szabadság, szerelem, Ext2 kell nekem.

(#13) BlackWoOd válasza [Kovi] (#9) üzenetére


BlackWoOd
aktív tag

Az én megoldásom a tiédtől alapvetően eltérne, de elvileg szögtartó pattogást alapból tartja, a szöget pedig az szintén képes tartani (igaz, nem teljesen pontosan, de neked is kerekítened kell...).

Az elv alapja, hogy kirakod a ''labdát'' a kezdő pozíciójába.
(mondjuk labdaX,labdaY koordinátákra)

Felveszel iránymódosító változókat (pl. deltaX, deltaY), amik meghatározzák a labda kövezkező mozgásának irányát (pl. deltaX = 1, deltaY = 1.5 esetén a labda balra lefelé mozog, lefelé 1.5-ször gyorsabban mint balra, stb.)

Minden körben lemódosítod a labdaX és labdaY-t a deltaX és deltaY-nal,
majd jönnek az ütközésvizsgáló if-ek.
Ha a labdaX vagy a labdaY kiesik valamelyik határon, csak a megfelelő deltaX előjelét módosítod, valamint ha pontosan akarsz dolgozni, a labdaX illetve labdaY értékét módosítod azzal az értékkel, amivel labdaX kijjebb esett a határon.

(Nem olyan bonyi, mint első olvasásra! :P )

De látom, már megoldódik a problémád! :)

< ..kevés az ember, sok az emberszerű lény... >

(#14) [Kovi] válasza Pizzafutar (#11) üzenetére


[Kovi]
tag

Köszi a tippet, double-re átírva tökéletesen megy.. nemtudom, hogy nem vettem észre, pedig már régebben is többször szívtam ilyen double <-> int konverzióknál történő levágásos kerekítés miatt. Viszont akkor lenne még egy kérdése.. igaz ezzel még nem is próbálkoztam, csak úgy eszembe jutott, hogy ha beraknék még egy labdát akkor azt is el kéne intézni hogy ha a két labda ütközik akkor mi történjen.. nah mostugye ez már nem olyan egyszerű, mert itt akkor arra is figyelni kell hogy egymáshoz képest hogyan helyezkednek el a labdák, és akkor a szög is változik amiben tovább haladnak.. szal a matematikai alapok érdekelnének, ha le tudnád írni, hogyan kell az ilyet elméletben megoldani..

Szabadság, szerelem, Ext2 kell nekem.

(#15) [Kovi] válasza BlackWoOd (#13) üzenetére


[Kovi]
tag

Köszi a tippet, így is biztos jó lenne, de asszem nem éri meg átírni, főleg hogy azért enyém sem bonyolultabb, max az a 2 sor ami számolja a következő koordinátát.. de határ ellenőrzés ugyan úgy kell mind2 esetben.. most meg hogy már az én megoldásommal is tökéletesen megy :C

Szerk: Viszont ha van vmi hasonlóan egyszerű megoldásod arra amit #14-ben írtam.. azt szívesen fogadom :))

[Szerkesztve]

Szabadság, szerelem, Ext2 kell nekem.

(#16) BaLinux válasza [Kovi] (#15) üzenetére


BaLinux
tag

De jó látni hogy van még rajtam kívül ember aki az ilyen szimulációkat szereti :)

A több labdás probléma már egy komoly dolog. Tavaly írtam egy 2d-s fizikai szimulátort c++-ban, ami támogatja a kör és poligon (konkáv is!) alapú ütközést. Egy lassan készülő kis játék fizikai motorja lesz amúgy. 2-3 hétig agyaltam rajta szüntelenül, összesen 77k kód.
A kör alapú, ami neked kell, még nem olyan bonyi, mert egyszerűen meghatározható minden labda-párra az az idő, amikor a jövőben adott aktuális sebességükkel ütközni fognak. A poligonos viszont már bonyolult, és pontatlan is, de azért működik.
Az ütközés számításához kell egy kis fizika (pl. én figyelembe veszem a tömeget, tehetetlenségi nyomatékot és rugalmasságot is).
Az ütközés csak abból áll, hogy az abban résztvevő objektumok sebessége megváltozik az adott összefüggések alapján.
A #13 hozzászólást intéző kollega által javasolt módszerrel kellene továbbvinni a programod, mert a tiéd a cos/sin miatt lassú, viszont közel ugyanolyan pontatlan, tehát nem sok előnye van.
Ha érdekel, szívesen segítek.

(#17) [Kovi]


[Kovi]
tag

up!
#14ben felvetett 2 labdás problémára vmi 5let?
Szerk: nemszóltam.. látom közben jött válasz..

[Szerkesztve]

Szabadság, szerelem, Ext2 kell nekem.

(#18) BaLinux válasza [Kovi] (#17) üzenetére


BaLinux
tag

Javaslom a #16-os hozzászólás áttanulmányozását! :)

(#19) Pizzafutar válasza [Kovi] (#14) üzenetére


Pizzafutar
aktív tag

Hmmm, ertem mire gondolsz.

Van 2 kor. Amikor utkoznek, a kulso pontjaik erinkeznek. Az erinto ekkor merroleges a pontok kozepet osszekoto egyenessel. Ugyanakkor a van mindegyik kornek egy-egy iranyvektora, amerre a korok mozognak. Ilyenkor ezeket az iranyvektorokat kell tukrozni az erintore. (ennek a specialis esete az eredeti peldaban a fal, ami 0 vagy 90 fokos erintonek felel meg.)
Ha lerajzolod, azthiszem ertheto!

(#20) [Kovi] válasza BaLinux (#16) üzenetére


[Kovi]
tag

Hát segítséget megköszönném.. igazából engem sebeség annyira nem zavar.. ezt a kis progit még elbírja AthlonXP :)) Meg nekem igazából csak egyetemen kéne bemutatnom ezt a progit. Fizikai hatások, szal tehetetlenség / gravitáció ilyesmi nekem nem kell csak simán az ütközés.. így gondolom azért valamivel egyszerűbb. Mert most berakok még egy kört akkor ott is tudom vizsgálni hogy azok befoglaló négyzetének koordinátái mikor egyeznek (szal ütközik a 2 labda), csak utána ugye nemtudom hogy hogyan kéne kiszámolni a szöget amiben tovább halad, mert ugye ez függ az irányoktól amikben haladnak a albdák az ütközés előtt, és ugye attól is hogy egymáshoz képest milyen pozícióben vannak mikor ütköznek. Én eltekintek olyasmitől hogy egyik labda esetleg nehezebb mint a másik, vagy hogy a sebességük és az ezekből adódó lenületük eltérő.. a 2 labda nálam teljesen azonos..

Szabadság, szerelem, Ext2 kell nekem.

(#21) [Kovi] válasza Pizzafutar (#19) üzenetére


[Kovi]
tag

Igen eddig én is eljutottam, hogy a két kör középpontját összekötöm és arra merőleges az érintő, és le is rajzoltam, csak ugye itt az érintő nem csak vízszintes / függőleges lehet mint a fal, szal így már nem csak egyet kell módosítani a két komponens közül hanem mind2-t, és ezt most így sajnos nem tudom matematikailag leírni..

Szabadság, szerelem, Ext2 kell nekem.

(#22) Pizzafutar válasza BaLinux (#16) üzenetére


Pizzafutar
aktív tag

Ok, de ha csak a kort nezunk, mar abban az esetben is bonyolultabb ez a pelda, mert figyelembe veszi az objektumok fizikai tulajdonságait is. It mar a mechanikabol kell kiindulni!
Egyébként igazad van!

(#23) Pizzafutar válasza [Kovi] (#21) üzenetére


Pizzafutar
aktív tag

Ok, a gyakorlatban nem olyan bonyolult.
1. Legyen a ket pont kozepet osszekoto szakasz allaszoge beta, az egyik labda iranyszoge alfa.
2 A ket szog kulonbsege delta, pozitiv szam

3. az uj irany: (180+beta) - delta

Valami ilyesmi, a tevedes fentartva :)

(#24) BaLinux válasza [Kovi] (#20) üzenetére


BaLinux
tag

Hát mondjuk ha csak kettő labdád van, akkor:
ütköznek <==> (labda1.x-labda2.x)^2+(labda1.y-labda2.y)^2 <= (labda1.r+labda2.r)^2

az ütközés kimenetele pedig a fenti egyenlőtlenség teljesülése esetén így számolható:
- van a két labda, L1 és L2, és ismertek a koordinátáik: (.x; .y)=P, sebességkomponenseik: (.vx; .vy)=V, és sugaruk: .r.

Az ütközési normálvektor: N=(L1.P-L2.P)/abs(L1.P-L2.P) (tehát normalizálom, 1 hosszú vektor az N, és az egyik kör közepébe mutat, -N meg a másik közepébe)
Ezután transzformálod a két sebességvektort az N-nel párhuzamos és merőleges komponenssű vektorrá:
L.V_N=(N.x*L.V.x+N.y*L.V.y ; -N.y*L.V.x+N.x*L.V.y)
(mindkettőre igaz) => az L1.V_N és L2.V_N vektorok ''x'' összetevője tehát most a normális irányú sebességük, ''y'' összetevője meg az erre merőleges sebességük.
Az egészet azért csináltuk, mert csak az ún. centrális sebességük változik az ütközéskör.
Fgv. táblázatból:
L1.U_N.x=((1+k)*(L1.m*L1.V_N.x + L2.m*L2.V_N.x)/(L1.m+L2.m) - k*L1.V_N)
L2.U_N.x=((1+k)*(L1.m*L1.V_N.x + L2.m*L2.V_N.x)/(L1.m+L2.m) - k*L2.V_N)
illetve
L1.U_N.y=L1.V_N.y
L2.U_N.y=L2.V_N.y
(ez maradt meg)
,
ahol az U_N vektor az új, ütközés utáni sebességvektor. Ja, itt van egy Lx.m, ami a tömegük (tőlem lehet 1 is...), k pedig az ütközési rugalmasság. (tőlem legyen 1)
Ezt most nyilván visszafelé is transzformálni kell a ''normál'' koorinátarendszerbe, tehát

L.U=(N.x*L.U_N.x-N.y*L.U_N.y ; N.y*L.U_N.x+N.x*L.U_N.y)

mindkét labdára.
Így a végső sebességeik tehát L1.U, L2.U.

Remélem érthető és nem b*sztam el valahol egy előjelet. :DD
(ezt a progim általánosabb függvényének spec paraméterezése)

[Szerkesztve]

(#25) [Kovi] válasza BaLinux (#24) üzenetére


[Kovi]
tag

Köszi a segítséget.. majd kifogom próbálni, de asszem holnapra elég lesz 1 labdával is bemutatni, aztán majd ha tanár kér bele még pár labdát akkor eljátszom ezzel is :)

Szabadság, szerelem, Ext2 kell nekem.

(#26) BaLinux válasza [Kovi] (#25) üzenetére


BaLinux
tag

Ejj, hát kipróbáltad már végre, vagy feleslegesen gépeltem ennyit? ;]

Útvonal

Fórumok  »  Szoftverfejlesztés  »  C++ / mfc pattogó labda, help! (téma lezárva)
Copyright © 2000-2024 PROHARDVER Informatikai Kft.