Strona Główna     FAQFAQ  SzukajSzukaj  UżytkownicyUżytkownicy  GrupyGrupy


Poprzedni temat :: Następny temat
[delphi] delphi: Rysowanie
Autor Wiadomość
pszaka 

  Wysłany: 2010-04-08, 11:48   [delphi] delphi: Rysowanie

Witam.
Piszę program w Delphi, który symuluje oddziaływania grawitacyjne wg mechaniki Newtona. Wygląda to tak, że mam 3 kuleczki, które ruszają się po oknie po elipsach, hiperbolach i innych nieregularnych torach. Te kuleczki zostawiają po sobie ślad w postaci linii na canvas.

Problem jest taki, że te linie wymazują się, gdy ruszę okno lub gdy kuleczka przetnie którąś z nich (jak gumka do mazania). Czytałem, że przy każdej zmianie okna cały canvas musi zostac narysowany od nowa, ale nie mam pojęcia, jak przerysować takie nieregularne kształty. Proszę o radę, jak ktoś ma pomysł
 
   
Asdef 
Administrator



Pomógł: 32 razy
Skąd: Lodz
Wysłany: 2010-04-08, 18:28   

a nie mozesz dane przechowywac w tablicy?
_________________
PCT szuka ludzi dobrej woli, którzy jak mają ciekawe artykuły pisane z własnej ręki, to oczywiście można je nadsyłać nawet z gościa, po zatwierdzeniu przez moderatora…
http://www.pctown.pl/submitnews.php
lub wysyłać na asdef(malpa)o2.pl
http://img528.imageshack.us/img528/3311/dn9ar.png
 
   
pszaka 

Wysłany: 2010-04-08, 19:08   

nie bardzo rozumie jak
 
   
ExeQtoR 
Moderator



Pomógł: 36 razy
Skąd: K.P.
Wysłany: 2010-04-08, 21:37   

hmmm Asdef, tablica w Delphim to nie zbyt dobra sprawa, zwłaszcza gdy nie zna się ilości punktów ;-( a tworzenia od nowa co chwile to troszkę nie za fajna metoda ;-)

moja opcja... co prawda NIE znam Canvas'a ale na szybko z czaiłem na Wiki, że to biblioteka którą rysujesz grafikę wektorową, podając współrzędne itp....

pytanie ile współrzędnych musisz podać chodzi o maxymalną wartość, lub ile różnych figur używasz???

na pytanie dlaczego się pytam, to mogę Ci powiedzieć że ja lubię bazy danych :D
-----------Do rzeczy --------------
mamy np. Koło(x,y i promień) [i inne dane, jeżeli są]
rbisz Rekord(tak to się nazywa w Delphi, w C++ to struktura)
type
wsk_kolo = ^tkolo;
tkolo = record {deklaracja rekordu}
x: Integer;
y: Integer;
r: Integer;
next: wsk_kolo;
end;

var
kolo_baza:tkolo;

i teraz tworzysz dynamicznie typ danych kolo_baza wiążesz go wskaźnikiem z następnym i tak w kółko tyle ile mamy utworzonych kółek, a w ostatnim wskaźniku dajesz NIL(chyba ja operuje teraz głownie w C++ to tam jest NULL),

i tak jak tworzysz nowy obiekt w Cavans to potrzeba nowy rekord zrobić, a jeżeli robisz kolejną figurę o innych parametrach, to tylko doklejasz do listy ;-) )))))))))))))))))

a później podpinasz się pod jakąś funkcję np. OnMouseClick i wykonujesz już szybkie rysowanie za pośrednictwem tych danych, już bez animacji i opóźnień dla użytkownika, więc ekran będzie tak szybko mrugał jak będziesz ruszał.... tak ja to widzę, bo w życiu nie używałem takiej grafiki ;-)

aha... kod pisany na szybko z głowy i Wikipedi xD pokazuje tylko idee i jak to ma być według mnie rozwiązane, tzn... chodzi o przechowywanie danych, można też do pliku zapisywać itp... coś wykombinować - po prostu trzeba pomyśleć ;-)

Pozdro :) )))
_________________
Moderatora grzecznie się słuchamy,
nie spamujemy, nie bluzgamy...


 
 
   
pszaka 

Wysłany: 2010-04-09, 08:53   

Na obrazku dołączam o jakie figury chodzi. Jak widać, nie są to kółka, i nie wystarczy podać kilku współrzędnych, lecz każdy piksel trzeba magazynować osobno. Myślałem o czymś w rodzaju matrycy jakiejś dużej powierzchni, na której jest rysowane i poprostu użyć pętli aby sprawdzała każdy punkt z osobna. Potem jakis Timer, żeby wszystko na bieżąco rysował. Nie wiem czy to dobry pomysł?

1.jpg
Plik ściągnięto 385 raz(y) 11,97 KB

 
   
ExeQtoR 
Moderator



Pomógł: 36 razy
Skąd: K.P.
Wysłany: 2010-04-09, 18:41   

No to sprawę skomplikowałeś, ale tylko dla kompa xD a dla siebie uprościłeś, jednak jak dla kompa komplikacja to i wydajność spada - taka prawda !

Więc tak masz racje ale ja sprecyzuje co trzeba by zrobić :-)

1pixel jest opisany następującymi wartościami(chodzi o sam kolor) RGB czyli od 0-255 to odpowiada w Delphi zmiennej Byte ;-)

robimy 1 strukturę pfff sorrry Rekord xD
type
TPixel = record
R:Byte;
G:Byte;
B:Byte;
end;

dalej ;-) rysunek płaski czyli płaszczyzna 2 wymiarowa, dlatego robimy to na tablicy dwu wymiarowej, prosto będzie jak znasz rozmiar pola do rysowania zanim odpalisz program napisany, jeżeli nie znasz, to dynamicznie to trzeba robić, a to troszkę więcej zachodu a jeżeli użytkownik sam powiększa pole do rysowania to jeszcze bardziej to komplikuje sprawę :-( ale wszystko da się zrobić ;-)

Więc do rzeczy ten obrazek ma: 693 x 402 pikseli
czyli tablica dwu wymiarowa 0-692x0-401 of TPixel ;-)

var
Baza_pixeli : array[0..692, 0..402] of TPixel;

i masz gotową bazę danych aktualnych pixelków i ich położenie,
Podczas rysowania danego pixela na Canvas, rysujesz również w bazie danych - tak virtualnie rysujesz, czyli ustawiasz parametry danego pixelka w bazie.

Dalej..... Timer odpada, to zamuli Ci kompa, bo byś musiał ustawić rysowanie z częstotliwością 75Hz czyli 75razy na sekundę czyli Timer na
1000 - 1s
75 - 13,4ms
czyli na ok 0,013, więc od razu przy takim odświeżaniu Cavansa czyli odczycie z bazy kolorków dla danego pixela to Ci procek(rdzeń) bo tylko 1-wątkowość jest obsługiwana na 100%

dlatego, pomyśl... co Ci kasuje "Cavansa" ?? ? przesuwanie, wiec odszukujesz na formie OnMouseClick, i takie inne które powodują kasowanie xD i pod to podpinasz się możesz użyć w tedy timera który tylko opóźni start od nowa rysowania na ok 0,050 i po takim czasie w np. OnMouseClick zacznie ponowne rysowanie, chodzi o to aby funkcja która ma za zadanie ponowne narysowanie Cavansa nie wyprzedziła kliknięcia xD w teorii nie wyprzedzi a w praktyce możesz sprawdzić ;-)

a ja bym to zrobił coś takiego,

Timer -> wywołuje funkcję sprawdzania(ustawiania Cavansa z bazy), jak wywoła to ma się wyłączyć czyli Timer1->enabled = false;

te różne funkcje np. OnMouseClick -> If (Timer1->Enabled == True) { "Wykonaj funkcje odświerzania 'Cavansa'", i ustaia Timer na 50ms)else{Timer1->enabled = true; Timer1->time = 50;}

to bym wpakował do każdego obiektu OnMouseClick i innych ;-)
mówię po co:
Jeżeli klikamy częściej niż co 0,05s to timer ustawiamy i tak na te 50s, ale żeby funkcja odświeżania zadziała to ją wywołujemy wcześniej(gdy timer jest aktywny), a jak zadziej klikamy to timer ja wywołuje, oczywiście te 0,05sekundy to skrajny przypadek, ale np. ruszanie forma już będzie takim przypadkiem bo jak szybko przesuwamy to zauważymy mruganie formy albo skok obciążenia procka ;-) ale efekt będzie utrzymany.

dla zabezpieczenia możesz ostawić jakiś inny dodatkowy timer2 co 1/4sekundy który odświeży Cavansa... ale to już strata czasu procesora, a jeżeli Timer1 zostanie użyty to zwiększa(ustawia od nowa) czas dla Timera2 tak aby utrzymać odpowiedni czas dodatkowego odświeżania, jak zawsze chodzi o to aby zmniejszyć użycie procka, ale jak dobrze wyłapiesz te momenty które kasują Cavansa to ten Timer2 jest zbędny ;-)

ogólnie lepiej jest nie urzywanie Timerów bo przy małych wartościach timera obciązają mocno procka ;-) ale decyzja nalezy do Ciebie

Ktoś ma jakieś inne propozycje ?? ?
_________________
Moderatora grzecznie się słuchamy,
nie spamujemy, nie bluzgamy...


 
 
   
Wyświetl posty z ostatnich:   
Odpowiedz do tematu
Możesz pisać nowe tematy
Możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach
Nie możesz załączać plików na tym forum
Możesz ściągać załączniki na tym forum
Dodaj temat do Ulubionych
Wersja do druku

Skocz do:  

Powered by phpBB modified by Przemo © 2003 phpBB Group - opowiadania
system walidacji dla gości opracował Petermechanic
Forum komputerowe
Strona wygenerowana w 0,11 sekundy. Zapytań do SQL: 13