CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - PaintBox i figury Voronoi, kreślenie błędne.
Strona 1 z 1

PaintBox i figury Voronoi, kreślenie błędne.

Nowy postNapisane: środa, 17 stycznia 2018, 12:49
przez lukagrom
Tłumaczę programik z książki o Visual C++ na środowisko C++ Builder.
W skrócie TrackaBarem wybieram wartość min=1 max=11 i wciskając button i na PaintBoxie wykreśla się wzorek.
w sekcji private umieszczam:
funkcje mat. do wyznaczenia odeglosci miedzy punktami, dekl tablicy kolorow - ilosc 11, funkcje inicjującą tryb losowania (rand()) i wypelnianie tablicy kolorow, oraz zmienna int, ktora na biezaca pokazuje wskazania z TrackBarra.

KOD cpp:     UKRYJ  
private:        // User declarations
   TColor colors[11];
   float __fastcall distance_of_Points(int a, int b, int c, int d);
   void __fastcall Init();
   int tr_Position;
 

W głownym programie wypełniam tablicę kolorów, defniuje funkcje wyliczającą odleglosci miedzy dwoma punktami, oraz aktywuje zmienną, ktora będzie przyjmowała wartość z TrackaBarra:
KOD cpp:     UKRYJ  
void __fastcall TForm1::Init()
 {
         srand(time(NULL));
         int i;
         for(i=0;i<11;i++)
         {
                 colors[i]=RGB(rand()%255,rand()%255,rand()%255);
         }
 }

float __fastcall TForm1::distance_of_Points(int a, int b, int c, int d)
{
        float value;
        value=sqrt(1.*((a-c)*(a-c))+((b-d)*(b-d)));
        return value;
}
void __fastcall TForm1::FormCreate(TObject *Sender)
{
 Init();
 tr_Position=TrackBar1->Position;
 Label3->Caption=IntToStr(tr_Position);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::TrackBar1Change(TObject *Sender)
{
  tr_Position=TrackBar1->Position;
  Label3->Caption=IntToStr(tr_Position);
}
 

Wszystko przebiega dobrze, kompilacja bez przeszkód.
Teraz najważniejsza część. Po kliknięciu w button, program wchodzi w zakres 3 pętli, z których 2 obejmują zakresem parametry dlugości i szerokość PaintBoxa(width,height), gdzie idęą jest wykorzystywanie metody: Canvas->Pixel. Czyli teroretycznie jakie kolory by PIXEL nie napotkał to i tak musi coś wykropkkować bo idzie punkt po punkcie po powierzchni PaintBoxa.
KOD cpp:     UKRYJ  
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 int *tab_X,*tab_Y;
 int point;
 float dist;
 tab_X=new int[11];
 tab_Y=new int[11];

 int i,j,k,x_Width,y_Height;
 for(i=0;i<tr_Position;i++)
 {
  x_Width=1+rand()%PaintBox1->Width;
  y_Height=1+rand()%PaintBox1->Height;
  tab_X[i]=x_Width;
  tab_Y[i]=y_Height;

 }
 for(i=0;i<PaintBox1->Width;i++)
 {

         for(j=0;j<PaintBox1->Height;j++)
         {

                   dist=30000;
                   for(k=0;k<tr_Position;k++)
                   {
                           if(distance_of_Points(i,j,tab_X[k],tab_Y[k])<dist)
                           {
                                   point=k;
                                   dist=distance_of_Points(i,j,tab_X[k],tab_Y[k]);
                           }
                   }
                   PaintBox1->Canvas->Pixels[i][j]=colors[point];



         }
 }

 delete tab_Y;
 delete tab_X;
}
 

I teraz w ogóle nie rozkminiam tego, dlaczego wykreśłany obraz na PaintBoxie (niezależnie jakie dam mu współrzedne) pojawia mi się tylko na pasku lewego boku komponentu, oraz połowa paska prawego boku komponentu, skoro metoda Canvas->Pixels "wędruje" w 2 pętlach punkt po punkcie po całej powierzchni komponentu. Sprawdzałem wszystkie zmienne tablicowe, które dostają wartości z zakresu rand()%, i tam nie ma jakiś przekroczonych zakresów. Powinno wszystko hulać, tak jak to się dzieje w śrowisku Visual C++ (choć tam jest to zupełnie inaczej napisane(ale matematyka współrzędnych identyczna)).

Re: PaintBox i figury Voronoi, kreślenie błędne.

Nowy postNapisane: czwartek, 18 stycznia 2018, 12:13
przez polymorphism
Próbowałeś malować w TPaintBox::OnPaint?

Dalczego tak:
KOD cpp:     UKRYJ  
 tab_X=new int[11];
 tab_Y=new int[11];

a nie tak:
KOD cpp:     UKRYJ  
int tab_X[11];
int tab_Y[11];

Re: PaintBox i figury Voronoi, kreślenie błędne.

Nowy postNapisane: piątek, 19 stycznia 2018, 16:19
przez lukagrom
W OnPaincie PaintBoxa identyczne wykreślanie, obejmujące jedynie wąski fragment komponentu. Zmienne dynamiczne to stare przyzwyczajenie, gdzie kiedyś mocno lansowano, że kod musi mieć najmniej pamięci, więc najlepiej wszystko zwalniać/uswuać po zakończeniu pracy.

Re: PaintBox i figury Voronoi, kreślenie błędne.

Nowy postNapisane: sobota, 20 stycznia 2018, 12:08
przez polymorphism
gdzie kiedyś mocno lansowano, że kod musi mieć najmniej pamięci, więc najlepiej wszystko zwalniać/uswuać po zakończeniu pracy.

To chyba jakaś prawda z lat 80/90. Dziś to bez znaczenia, tym bardziej że zmienne automatyczne są usuwane* z pamięci zaraz po wyjściu z funkcji. Tworzenie zmiennych lokalnych jest nie dość że szybsze, to jeszcze nie musi oznaczać większego zużycia pamięci.


*) usuwane teoretycznie, bo są tworzone w pamięci stosu, która istnieje przez cały czas trwania procesu.



W OnPaincie PaintBoxa identyczne wykreślanie

Próbowałeś rysować od razu po oknie, bez PaintBoxa?

Re: PaintBox i figury Voronoi, kreślenie błędne.

Nowy postNapisane: niedziela, 21 stycznia 2018, 13:56
przez lukagrom
Jednak matematyka. Zakres wykreślania obszaru na PaintBoxie jest uzależniony od jego kształtu i wymiaru. Najlepsze rezultaty przyjmuje dla kwadratu 500na500. Nie chcę już się w gryzać w te pętle i funkcje na obliczanie odległości punktów, ale pewnie tam są jakieś niuanse, gdzie nie cały obszar dostaje losowany kolor.