Qt QGraphicsScene - tablica/mapa sceny

0

W programie korzystam z QGraphicsScene i graficznego widgetu do jej wizualizaji. Na scenie będzie się znajdować n (na oko 100 < 1000) prostych obiektów (QGraphicsItem - ale nie wiem czy w tym wypadku to dobre rozwiązanie) o wymiarach 1x1 max 4x4 pixele (do ustalenia). Obiekty będą się przemieszczać w sumie na okrągło. I potrzeba mi tak jakby tablica sceny (o rozmiarach sceny nxm) i uzupełniona np. 0-wolne pole, 1-jakiś obiekt. Chodzi mi głównie o kolizje ale nie tylko.

Po prostu taka tablica strasznie ułatwiła by mi dalszą część programu.

Do głowy mi przychodzi tylko 1 pomysł - mając jakiś kontener graficznych obiektów i na bieżąco, pojedynczo wyłapywać z nich pozycje X i Y i zapisywać do zwykłej tablicy + ewentulanie ich wys i szer. Ale myślę że to będzie mało wydajne...

Byłbym wdzięczny za jakieś sugestie...

0

najpierw napisz to tak by ktoś był w stanie zrozumieć po jednym czytaniu.
Dobra rada: zamiast pisać jak chcesz coś zrobić, napisz najpierw co chcesz zrobić

0

Może troszkę zamotałem...

Mając graficzną scenę o rozmiarach 100x100 chcę stworzyć tablicę[100][100] np. intów. I wypełnić tą tablicę wartościami 0 - jeśli w danym punkcje sceny nie ma żadnego obiektu, 1 - na scenie znajduję się jakiś obiekt.

Na scenie znajdują się obiekty np. kwadraty (QGraphicsItem) o rozmiarach 2x2. Obiekty cały czas sie przemieszczją.

Program ogólnie ma symulować mieszanie się gazów. Nie wiem co jeszcze mogę dodać...

0

a zadales sobie trud by zagladnac do dokumentaci ?
elementy listujesz metoda:
QList<QGraphicsItem *> QGraphicsScene::items ( Qt::SortOrder order ) const , badz jedna z blizniaczych metod
a potem z kazdego itemka wyciagasz polozenie
pamietaj ze w jednym miejscu moze sie znajdowac wiecej niz jeden element
masz tez dostepna metode do listowania elementow ktore koliduja z wyszczegolnionym itemkiem
QList<QGraphicsItem *> QGraphicsScene::collidingItems ( const QGraphicsItem * item, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape ) const

0

na razie wygląda na to, że mieszasz problem graficzny z problemem czysto obliczeniowym. Obiektów graficznych (w dowolnym framework'u) nie używa się do obliczeń, ale do prezentacji wyników obliczeń.
Napisałeś symulacja mieszania się gazów. Jaką metodą: automat komórkowy, Monte Carlo, czy dokładna symulacja (leap-frog, Verlet, ...). Rozumiem, że jest to problem 2d.

Jak już pisałem napisz co chcesz uzyskać (na razie wiadomo coś o symulacji mieszania się gazów), bo ten zdawkowy opis jak chcesz to zrobić jest niepokojący.
Jeśli ci się to nie uda, to na miejscu moderatora posłałbym ten temat do kosza.

0

Aplikacje już napisałem. Problem byl z wydajnoscia, dla wiecej niz 1000 elementow symulacja zwalniala - tzn wykonywala sie wolniej niz przeskok timera.

fake_nick - wiem jak dzialaja te metody. Przeciez cos podobego sugerowalem w 1 poscie.

A Czy ważne jaka metoda ? Chodzilo mi bardziej o najoptymalniejszy sposob i stosunkowo prosty aby taka tablice stworzyc. Wlasnie po to aby obliczenia odzielic od graficznej prezentacji. Ewentualnie pare rad odnosnie jakich gotowych klas uzyc (np. slyszalem ze na pixmapie bylo by szybciej).

A tak zrobilem po swojemu i moze nie najlepszym sposobem - przez spadek plynnosci. Teraz ewentualnie moge doczytac...

0

najszybciej by bylo operowac na wlasnej monochromatycznej tablicy pikseli
potem na jej podstawie tworzysz QImage ( dane nie sa kopiowane wiec jest to szybkie )
z QImage tworzysz QPixmap ( niestety chyba trzeba kopiowac )
a QPixmape mozesz podpiac juz pod QLabel

0

Cudów nie ma, przy tak ogólnikowym postawieniu pytania konkretnej odpowiedzi raczej nie dostaniesz.
A radzę użyć jakiego profilera (pod Linuxem valgrind) i ustalić, w którym miejscu aplikacja spędza najwięcej czasu podczas symulacji i na tej podstawie próbować znaleźć miejsce do optymalizacji.

0

Imo wąskim gardłem jest sama graficzna scena QGraphicsScene i graficzne obiekty QGraphicsItem.

bo nawet jeśli zrobimy tak (pseudokod)

item to normalny QGraphicsItem (nawet kwadrat o wymiarach 1x1, Scena/Widok to 500x500)

for (int i = 0; i < items.size(); ++i) // item.size = np. 2000
{
     int r = random(4) + 1;
     if (r == 1) item[i].pos().x() + 1;
     // if (r == 2) ..... i tak dalej
}

całość zawrzemy w jakimś slocie i podepniemy pod timer (przeskok np. 20ms) to całość może nie wyrobić z rysowaniem.
Dużo zależy od procesora w domu na Athlonie x2 4200+ mulio a na i7 na uczelni biegało jak głupie - ale też do czasu:)
Oczywiście mój kod miał dodatkowo warunki brzegowe, kolizje i trochę bardziej złożone ustalanie nowej pozycji.
Ale właśnie to tak na prawdę nie ważne bo nawet przy ww kodzie program będzie mulil i tak jak fake_nick napisał lepiej było by na pixmapie robić tego typu rzeczy :)

0

Pogrzeb we flagach optymalizacyjnych QGraphicsView takich jak CacheModeFlag OptimizationFlag ViewportUpdateMode.
Poszukaj też jak zaprząc OpenGL w QGraphicsView (pogooglaj sam) wtedy cześć operacji przejmie karta graficzna.

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