Transformationen von Grafiken (verschieben, drehen, skalieren)



  • Guten Tag,

    ich muss folgende Aufgabe lösen:

    In einer Pricture - Box soll ich Verschiedene Formen (Rechtecke, Kreise, Ellipsen) erzeugen, welche verschieden groß sind. Dazu bin ich ja noch in der Lage, jedoch soll ich nun jene Objekte verschieben (bzw. drehen und skalieren!?) und innerhalb der Picture - Box bewegen. Falls die Objekte den Rand der Picture Box treffen, sollen diese davon "abprallen".

    Vielleicht habe ich auch einen falschen Lösungsansatz, da ich zwar Grafiken zeichne, jedoch keinerlei Information über Position etc. speichere, wäre auch hier für Hilfe dankbar !

    Ich wäre sehr hilfreich, wenn sie mir helfen könnten, habe lange zeit nach Lösungen gesucht, jedoch nicht gefunden ...

    mfG Thomas

    private: System::Void pictureBox1_Paint(System::Object^  sender, System::Windows::Forms::PaintEventArgs^  e) {
    
    			 Graphics^ g = e->Graphics;
    
    			 Random ^matrix1 = gcnew Random(); //Benutze Klasse Random, um Zufallszahlen zu erzeugen,
    												//für verschiedene Größen der Kreise und Rechtecke
    
    			int height,width,x,y,i,radius;
    
    			for(i=0;i<5;i++) //erzeuge 5 Rechtecke
    			{
    
    				height = matrix1->Next(30,60); // erzeugt Zufallszahl für Höhe zwischen 30 und 60
    				width = matrix1->Next(30,60);
    				x = matrix1->Next(0,pictureBox1->Width - width); //erzeugt Zufallszahl für x -Koordinate
    																 //wobei beachtet wird, das nicht außerhalb der Picture
    																//Box gezeichnet wird
    				y = matrix1->Next(0,pictureBox1->Height - height);
    
    				 g->FillRectangle(Brushes::Red,x,y,width,height); // gefüllte Rechtecke erzeugen
    
    			}
    
    			for(i=0;i<5;i++) //die gleiche Prozedur für die kreise
    			{
    				radius = matrix1->Next(30,60);
    
    					x = matrix1->Next(0,300 - radius);
    					y = matrix1->Next(0,300 - radius);
    
    				g->FillPie(Brushes::Orange,x,y,radius,radius,0,360);
    
    				lbl_Size->Text = "Breite: " + Convert::ToString(pictureBox1->Width) + "\n" +
    								"Höhe: " + Convert::ToString(pictureBox1->Height);
    
    			}
    
    		 }
    };
    


  • Ja, erstell dir geeignete Objekte und speichere sie in einer Liste. In der OnPaint Methode zeichenst du dann nur noch alle Objekte aus der Liste, ihre Eigenschaften modifizierst du woanders, z.B. nach Mausevents oder in einem Timer oder was auch immer du brauchst.



  • Danke für die rasche Antwort,

    jedoch bin ich nicht wirklich aufs C++ Programmieren spezialisiert, wäre es sehr viel Arbeit, ein Programm zu schreiben das (wenn auch nur 1) Rechteck durch eien Picture Box fliegen lässt ?

    mfG



  • Ist ja auch nicht wirklich C++, das ist mehr .NET 😉 Nö, viel Aufwand wärs nicht, vielleicht so 10-15 Minuten, wenn mans gleich hinkriegt oder paar Minuten länger, wenn man doch ein bisschen rumtüfteln muss.



  • Ja, stimmt auch wieder 🙂

    Naja, wären Sie so gut ? ^^ Wäre ihnen sehr dankbar dafür !

    mfG



  • Mir ist noch etwas eingefallen ...

    Wie fragt man ab, ob beim Windows - Farb - Dialog "OK" gedrückt wurde ? Hab schon einiges versucht aber leider nicht hinbekommen ...

    Color^ col = gcnew Color(); //neue Farb -  Variable Anlegen vom Typ (Klasse) Color
    			colorDialog1 ->ShowDialog(); //Farbdialog zeigen
    
    //hier sollte man abfragen - aber wie !?
    
    pen2->Color = colorDialog1->Color;
    


  • Die ShowDiwlog Methode liefert einen Rückgabewert... da Du vielleicht selber in einem Form bist und es dann zu Namenskonflikten kommt, musst Du ein ::System::Windows::Forms::DialogResult::Ok verwenden...



  • Nee, für andere zu programmieren hab ich keine Lust, und andere auch nicht nehm ich an. Außerdem würdest du dabei nichts lernen. Hausaufgaben muss man schon selber lösen.
    Wegen dem Farbdialog, und allen anderen Dialogen, ShowDialog gibt DialogResult zurück, da musst nur noch abfragen, obs DialogResult::OK war.



  • Naja, ist eigentlich etwas freiwilliges mehr oder weniger, ist leider schade, weil ich nicht draufkomme und mein Kollege auch nicht 😕

    mfG



  • dankeschön, das mit der DialogBox hab ich jetzt 🙂

    naja, falls sich doch wer die Zeit nehmen würde wäre ich sehr erfreut darüber !

    mfG Gerbi



  • So, eine weitere Frage ist angekommen ...

    Ich will die Picture Box per Button - Klick neu zeichnen (also paint - Ereigniss neu aufrufen ...). Jedoch funktioniert das nicht ganz wie ich will ... Es wird zwar neu gezeicznet, jedoch genau daneben und nicht anstatt der "alten" Picture Box. Das ganze funktioniert auch nur 1 Mal !

    private: 
    	PictureBox^ pictureBox1;
    	System::Void btn_load_Click(System::Object^  sender, System::EventArgs^  e) {
    
    			pictureBox1 = gcnew PictureBox;
    
          // Dock the PictureBox to the form and set its background to white.
    		pictureBox1->Location = System::Drawing::Point(0, 0);
    		pictureBox1->Size = System::Drawing::Size(350, 410);
    		 pictureBox1->Dock = DockStyle::Fill;
    		 pictureBox1->BackColor = Color::White;
    
          // Connect the Paint event of the PictureBox to the event handler method.
          pictureBox1->Paint += gcnew System::Windows::Forms::PaintEventHandler( this, &Form1::pictureBox1_Paint );
    
          // Add the PictureBox control to the Form.
          this->Controls->Add( pictureBox1 );
    		 }
    


  • Dann solltest Du die "alte" mit Remove entfernen.
    Und die "neue" PictureBox wird nicht nur einmal erstellt, sondern jedesmal wenn der Button geklickt wird.
    Die "neue" Box wird über die "alte" Box gelegt.

    Gruß

    Doug_HH



  • Und wo muss ich dann diesen "Remove" - Befehl hinschreiben ?

    mfG



  • Du brauchst keine neue PictureBox erstellen oder sonst was, du musst nur Invalidate aufrufen.



  • Hab das jetzt im Click Ereignis aufgerufen ... Es macht mir dennoch eine Picture Box daneben wieder hin ... Dann kommt nochmals der Farbdialog und dann zeichnet es die erste wieder neu !

    Vollständiger Code:

    #pragma endregion
    	private: System::Void btn_generate_Click(System::Object^  sender, System::EventArgs^  e) {
    
    				Random ^matrix = gcnew Random();
    
    				lbl_Zufallszahl->Text =  "Zufallszahl: " + matrix->Next(Convert::ToInt32(textBox1->Text),
    																		Convert::ToInt32(textBox2->Text));
    			 }
    private: System::Void textBox1_KeyPress(System::Object^  sender, System::Windows::Forms::KeyPressEventArgs^  e) {
    
    			 char key;
    
    			 key = e->KeyChar;
    
    			 if((key < '0' || key > '9') && key != 8)
    			 {
    					e->KeyChar = 0; //Bewirkt, dass das "fehlerhafte" Zeichen nicht
    									//in der Textbox angezeigt wird
    			 }
    		 }
    private: System::Void textBox2_KeyPress(System::Object^  sender, System::Windows::Forms::KeyPressEventArgs^  e) {
    
    			 char key1;
    
    			 key1 = e->KeyChar;
    
    			 if((key1 < '0' || key1 > '9') && key1 != 8)
    			 {
    					e->KeyChar = 0; //Bewirkt, dass das "fehlerhafte" Zeichen nicht
    									//in der Textbox angezeigt wird
    			 }
    		 }
    private: System::Void pictureBox1_Paint(System::Object^  sender, System::Windows::Forms::PaintEventArgs^  e) {
    
    			 Graphics^ g = e->Graphics;
    
    			 Random^ matrix1 = gcnew Random(); //Benutze Klasse Random, um Zufallszahlen zu erzeugen,
    												//für verschiedene Größen der Kreise und Rechtecke
    
    			int height,width,x,y,i,radius;
    
    			 unsigned char r,gr,b;
    
    			r = matrix1->Next(0,255);  //Variable für Rot anlegen
    			gr = matrix1->Next(0,255); //Variable für Grün anlegen
    			b = matrix1->Next(0,255); //Variable für Blau anlegen
    
    			Color^ col = gcnew Color(); //neue Farb -  Variable Anlegen vom Typ (Klasse) Color
    
    			Pen^ pen1 = gcnew Pen(Color::FromArgb(255, r, gr, b)); //Pen 1 mit zufälligen Farben erzeugen
    			pen1->Width = matrix1->Next(3,5);	                   //Zufällige Randstärke 							
    
    			Pen^ pen2 = gcnew Pen(Color::FromArgb(255, r, gr, b)); //Pen 2 mit zufälligen Farben erzeugen(später überschrieben)
    			pen2->Width = 3;										//Randstärke auf 3Pt setzen
    
    			if(colorDialog1->ShowDialog() == ::System::Windows::Forms::DialogResult::OK) //Dialogbox anzeigen und 
    																						//abfragen, ob in der Dialog - 
    																						//Box "OK" gedrückt wurde
    			{
    				pen2->Color = colorDialog1->Color;						//Schreiben der gewählten Farbe auf Pen2
    			}
    
    			 for(i=0;i<5;i++)
    			 {
    
    				height = matrix1->Next(30,60); // erzeugt Zufallszahl für Höhe zwischen 30 und 60
    				width = matrix1->Next(30,60);
    
    				x = matrix1->Next(0,pictureBox1->Width - width); //erzeugt Zufallszahl für x -Koordinate
    																	 //wobei beachtet wird, das nicht außerhalb der Picture
    																	//Box gezeichnet wird
    				y = matrix1->Next(0,pictureBox1->Height - height);
    
    				g->DrawRectangle(pen1,x,y,width,height);
    
    			 }
    
    			for(i=0;i<5;i++) //erzeuge 5 Rechtecke
    			{
    
    				height = matrix1->Next(30,60); // erzeugt Zufallszahl für Höhe zwischen 30 und 60
    				width = matrix1->Next(30,60);
    				x = matrix1->Next(0,pictureBox1->Width - width); //erzeugt Zufallszahl für x -Koordinate
    																 //wobei beachtet wird, das nicht außerhalb der Picture
    																//Box gezeichnet wird
    				y = matrix1->Next(0,pictureBox1->Height - height);
    
    				g->DrawRectangle(pen2,x,y,width,height); // gefüllte Rechtecke erzeugen
    
    			}
    
    			for(i=0;i<5;i++) //die gleiche Prozedur für die Kreise
    			{
    				radius = matrix1->Next(20,50);
    
    				x = matrix1->Next(0,pictureBox1->Width - radius);  // erzeugt Zufallszahl für x-Koordinate zwischen 30 und 60
    				y = matrix1->Next(0,pictureBox1->Height - radius); // erzeugt Zufallszahl für y-Koordinate zwischen 30 und 60
    
    				g->FillPie(Brushes::Orange,x,y,radius,radius,0,360); //Zeichne Kreis
    
    			}
    
    			lbl_Size->Text = "Breite: " + Convert::ToString(pictureBox1->Width) + "\n" +
    								"Höhe: " + Convert::ToString(pictureBox1->Height);
    
    		 }
    private: 
    	PictureBox^ pictureBox1;
    	System::Void btn_load_Click(System::Object^  sender, System::EventArgs^  e) {
    
    		pictureBox1->Invalidate();
    		pictureBox1 = gcnew PictureBox;
    
          // Dock the PictureBox to the form and set its background to white.
    		pictureBox1->Location = System::Drawing::Point(0, 0);
    		pictureBox1->Size = System::Drawing::Size(350, 410);
    		 pictureBox1->Dock = DockStyle::Fill;
    		 pictureBox1->BackColor = Color::White;
    
          // Connect the Paint event of the PictureBox to the event handler method.
          pictureBox1->Paint += gcnew System::Windows::Forms::PaintEventHandler( this, &Form1::pictureBox1_Paint );
    
          // Add the PictureBox control to the Form.
          this->Controls->Add( pictureBox1 );
    		 }
    };
    }
    

Anmelden zum Antworten