Gezeichnetes rückgängig machen******

Aj2010

Mitglied
Hi. Ich hab diesmal etwas komplizierteres (für mich zumindest)
Da ich im net nichts sinnvolles gefunden habe schreib ich euch mal mein Anliegen.

Und zwar. Ich kann ja mittlerweile zeichnen. Bin auch ganz stolz darauf =)
Problem ist nun, ich hab als Aufgabe bekommen, dass Ich das Gezeichnete auch wieder Rückgängig machen muss. Also radieren.

Die Koordinaten werden in einem Array gespeichert. Und jedes Abgeschlossene Element ist ein Objekt, in dem die Koords als Array hinterlegt sind. Ich weiß, wie ich das Gezeichnete weiß machen kann.

Das darf aber nicht sein. es muss der entsprechende Farbcode zurück geführt werden. und zwar willkürlich an einem Beliebigen Punkt im Bild. Ich kann euch ja mal die entsprechenden Code-Teile geben. Ich bin mir nur nicht sicher ob das der Effizienteste Weg ist, da das Zeichnen So definitiv zu langsam ist...

Code:
void Form1::pictureBox1_MouseDown(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e) {
			 if(e->Button == System::Windows::Forms::MouseButtons::Left && !radieren) {
				mouseDown = true;
				point->Add(gcnew SchreibKoordinaten(e->X + hScrollBar1->Value,e->Y + vScrollBar1->Value));
				layer->FillRectangle(Brushes::Black,e->X + hScrollBar1->Value,e->Y + vScrollBar1->Value, 2, 2);
				pictureBox1->Invalidate();
				 }
			 if(e->Button == System::Windows::Forms::MouseButtons::Left && radieren) {
				 c = kopie->GetPixel(e->X + hScrollBar1->Value,e->Y + vScrollBar1->Value);
				 layer->SetPixel(e->X + hScrollBar1->Value,e->Y + vScrollBar1->Value,Color::FromArgb(c.A,c.R,c.G,c.B));
			 }
		 }
	void Form1::pictureBox1_MouseMove(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e) {
			  
			  if(mouseDown && !radieren) {
				  
				 p = Point(e->X + hScrollBar1->Value, e->Y + vScrollBar1->Value);
				 layer->DrawLine(pen1, point[anzahl_gezeichnet]->getKoord(),p);
				 point[anzahl_gezeichnet]->setKoord(e->X + hScrollBar1->Value, e->Y + vScrollBar1->Value);
				 region1 = gcnew System::Drawing::Region(Rectangle(e->X + hScrollBar1->Value -20, e->Y + vScrollBar1->Value-20, 40,40));
					 pictureBox1->Invalidate(region1);
			  }

			   if(mouseDown && radieren) {

			   }
		 }
	void Form1::pictureBox1_MouseUp(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e) {
			 if(e->Button == System::Windows::Forms::MouseButtons::Left) {
				if(mouseDown && !radieren) {
					 p = Point(e->X + hScrollBar1->Value, e->Y + vScrollBar1->Value);
					 layer->DrawLine(pen1, point[anzahl_gezeichnet]->getKoord(),p);
					 point[anzahl_gezeichnet]->setKoord(e->X + hScrollBar1->Value, e->Y + hScrollBar1->Value);
					 mouseDown = false;
					 pictureBox1->Invalidate();
					 tester = gcnew HackenTest(point[anzahl_gezeichnet]->listAusgabe());
					 if(tester->istHacken()) {
						aufbauAntworten();
						contM->Show(pictureBox1,point[anzahl_gezeichnet]->getKoord() );
						}
					 ++anzahl_gezeichnet;
				}
				if(mouseDown && !radieren) {

				}
			 }
		 }

Das mit dem Radieren ist eine zusatz Boolsche variable, damit ich das getrennt gehalten bekomme.

Ich weiß, die Methoden werden jetzt durch das Radieren sehr lang, oder sollte ich da noch zusätzliche Methoden für nutzen? und ist der Ansatz der richtige um die Originalpunkte wiederherzustellen?
 
Diese Problematik ist eine ganz grundlegende und betrifft nicht nur dich. Das ist auch der Grund warum es so viele Frameworks/Implementationen gibt dieses zu realisieren.

Ein sauberes Rückgängig (vielleicht sogar beliebig oft mal) kann nur verwaltende Klassen, die die Zustände speichern und wiederherstellen kann, erledigt werden.

Hier einpaar die ich im Netz gefunden habe:

http://dotnet-snippets.de/dns/multiples-undoredo-SID1287.aspx
http://www.codeproject.com/KB/cs/generic_undo_redo.aspx
http://www.codeproject.com/KB/cs/useractionbasedundoredo.aspx
http://www.codeproject.com/KB/cs/undoredobuffer.aspx

Dir wird wohl bei den Wünschen nichts so viel anderes übrig bleiben, als dich in das Thema einzuarbeiten. Dies wird dir aber bei weiteren Änderungen/Anpassungen und Wünschen einiges an Zeit und Ärger ersparen und vor allem ist es was ganz Grundlegendes was du garantiert irgendwann wieder gebrauchen kannst.

Gruß
 
Hab jetzt nochmal mit meinem chef gesprochen wie er das nun genau meint.

Zu erst einmal will er an beliebiger Stelle ein gezeichnetes Objekt rückgängig machen. Heißt, dass die Objekte einen unsichtbaren Rand bekommen. Ich denk mal, dass muss ich über einige schleifen machen, damit das überprüft wird, ob das Objekt existiert.

Ich versuch mal was hinzubiegen. =)
 
naja, ich denke mal für den anwender ist es etwas kompliziert genau ein pixel zu treffen um das objekt zu löschen...

um deine frage zu beantworten nein. Ich zeichne ja auf einem Bild herum. Gleichzeitig, sofern ein häckchen gezeichnet wurde, wird eine antwort in das objekt geschrieben. also eine zuordnung. Wenn ich dann in den Modus radieren gehe, soll ein beliebiges Objekt an einer beliebigen Position gelöscht werden, die Original-Bildpunkte wiederhergestellt und Die Zuordnung gelöst werden, falls eine zuordnung besteht... der anwender kann nämlich auch auf dem Bild schreiben.

Ich hab da heute was gefunden, was eventuell machbar wäre. Wobei dann das Kann-Kriterium nicht erfüllt werden würde. Bzw. nur halb.

http://msdn.microsoft.com/de-de/library/system.drawing.graphics.save.aspx

dass ist Das, was ich gesucht habe. Nur mit dem Unterschied, Ich kann dann wieder nicht zwischendurch löschen, was ja eigentlich gemacht werden müsste.

Ich hab mir grad von einem Kollegen sagen lassen, dass Photoshop so auch arbeitet. also ab einem gewissen Punkt weiter arbeiten. Jedoch geht alles, was danach gemacht wurde verloren.... Habt Ihr dazu eine bessere Variante?
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück