Guten Tag zusammen,
meine Anforderung könnte schon fast ins Programmier Spiel passen 😃
In einer von der Größe frei definierbaren Matrix (gegeben sei jetzt mal 3x3) wird ein Kabel verlegt. Bekannt ist quasi nur Start und Endpunkt.
Somit wird in Schlangenlinien das Raster von oben nach unten befüllt.
for (int y = 0; y < gridHeight;y++)
{
for (int x = 0; x < gridWidth; x++)
{
if (y == 0 || y % 2 == 0)
xI = x;
else
xI = gridWidth-1 - x;
Rectangle myRectangle = new Rectangle(this.Padding.Left + (xI * pixelWidth) + (this.Padding.Right * xI), this.Padding.Top + (y * pixelHeight) + (this.Padding.Bottom * y), pixelWidth, pixelHeight);
_listgo.Add(new MyFilledRectangle(new SolidBrush(Color.Red, myRectangle));
}
}
Ergebis:
1 2 3
6 5 4
7 8 9
Prinzipiell kein Problem. Nun möchte ich aber alle 8 möglichen Start<>End Kombinationen darstellen und komme nicht so recht weiter.
Mit einer Hilfsvariablen yI könnte ich jetzt noch von unten nach oben darstellen, aber dann müsste ich schon anfangen die beiden Schleifen zu vertauschen und erst x zu durchlaufen und dann y durch zu iterieren.
Mein Enum für die Richtungen sieht aktuell so aus:
public enum FlowDirection
{
UpperLeftToRight = 1,
UpperLeftToBottom = 2,
UpperRightToLeft = 3,
UpperRightToBottom = 4,
RightBottomUp = 5,
RightBottomToLeft = 6,
LeftBottomUp = 7,
LeftBottomToRight = 8
}
Hat jemand schonmal ein ähnliches Problem einigermaßen elegant gelöst?
Aktuell überlege ich schon ob ich einfach ein Konstrukt wie folgt baue damit wenigstens eine minimale Übersicht gewahrt bliebe:
for(i=0,i< gridWidth*gridHeight;i++)
switch(flow)
{
case FlowDirection.UpperLeftToRight:
y++;
x--;
break;
}
DrawPixel(x,y);
(Eben aus dem Kopf hier hineingepfuscht)
Vielleicht sehe ich auch gerade nur den Wald vor Bäumen nicht. Freitag Mittag eben 😉
Du musst dir eigentlich nur merken ob du zeilenweise nach oben/unten oder spaltenweise nach links/rechts laufen willst und in welche Richtung du gerade in der anderen Dimension läufst. Was der Startpunkt war ist dabei egal.
Beispiel. Du beginnst links oben und willst zeilenweise nach unten. Erst mal gehts nach rechts ... rechts ... rechts bis es nicht mehr weiter geht.
Dann geht es unten weiter, siehe Merker "zeilenweise nach unten".
Dann gehts nach links (weil nur links übrig bleibt), links, links ... bis wieder zum Rand.
Wenn du nicht mehr weiter runter kannst, bist du fertig.
Hallo trib,
also ich würde einfach folgendes machen:
int i = 0;
for (int y = 0; y < numLines; y++) {
for (int x = 0; x < lineLength; x++) {
DrawPixel (x, y, ++i);
}
}
Wobei es um virtuelle Zeilen geht, die je nach Orientierung physische Zeilen oder physische Spalten sind. numLines entspricht also je nach Orientierung entweder der Höhe oder der Breite. Analog, nur andersherum für lineLength.
Und in DrawPixel machst du dann einen switch für das Umrechnen der virtuellen Koordinaten in die physischen Koordinaten. Zum Beispiel wäre bei UpperLeftToRight keine Umsetzung erforderlich, bei UpperLeftToBottom würden x und y einfach vertauscht und bei UpperRightToLeft würde x zu lineLength - x usw.
herbivore
Hier mal so ganz grob wie es funktionieren müsste von der Logik her.
x=0
y=0
x++
y++
drawPixel
xmax = 10;
ymax = 100;
wenn ymax % 10 == 0 dann andere richtung
y++
x--
drawPixel
so müsstest du schon eine Vertikale Parabel erzeugen du muss halt nur noch eine if anweisung einfügen die darauf acht das du nach der ersten kurve immer 2x in die selbe richtung gehst. also sogesehen dann ymax % 20 == 0
Ich hoffe das hilft dir weiter 😉
Real programmers don't comment their code - it was hard to write, it should be hard to understand.
Guten Tag zusammen,
erstmal vielen Dank für die Antworten!
chilic´s klingt erstmal als die simpelste. Allerdings muss ich mir merken ob ich Spalten oder Zeilenweise vorgehe und wohin ich meinen Startpunkt setzen muss. Möchte ich nun über das Zeichen hinaus gehen und z.B. auf meinen Punkt klicken, muss ich aus der Position wieder zurückrechnen. Dafür eignet sich die Methode so nicht ganz.
Die Lösung von Crone habe ich auch schnell präferiert. Bis ich auf die Problematik gestoßen bin, wenn ich von der "norm" 10x10 abweiche und z.B. 11x9 als Matrix auswähle. Im Nachhinein gesehen war das aber nur ein Rechenfehler, den ich da eingebaut habe.
Dann stehe ich aber genauso vor dem Problem, keinen Pixel allein ansprechen zu können, sondern immer eine Schleife benötige.
Letztendlich hatte ich schon begonnen herbivore´s Vorschlag mit einer switch-Anweisung zu programmieren. Sieht zwar relativ unübersichtlich aus (wie ich schon vermutet hatte) aber ist dann schnell erledigt, wenn man das Prinzip verstanden hat.
private void DrawPixel(int pixelNo)
{
int x = 0;
int y = 0;
switch(pixelFlow)
{
case FlowDirection.UpperLeftToRight:
y = pixelNo / gridWidth;
if(y%2==0)
x = pixelNo % gridWidth;
else
x = (gridWidth - 1) - pixelNo % gridWidth;
break;
case FlowDirection.UpperLeftToBottom:
x = pixelNo / gridHeight;
if(x%2==0)
y = pixelNo % gridHeight;
else
y = (gridHeight - 1) - pixelNo %gridHeight;
break;
case FlowDirection.UpperRightToLeft:
y = pixelNo / gridWidth;
if (y % 2 == 0)
x = (gridWidth -1) - (pixelNo % gridWidth);
else
x = pixelNo % gridWidth;
break;
case FlowDirection.UpperRightToBottom:
x = (gridWidth -1) - pixelNo / gridHeight;
if ((pixelNo / gridHeight) % 2 == 0)
y = pixelNo % gridHeight;
else
y = (gridHeight - 1) - pixelNo % gridHeight;
break;
case FlowDirection.RightBottomUp:
x = (gridWidth -1) - pixelNo / gridHeight;
if ((pixelNo / gridHeight) % 2 == 0)
y = (gridHeight - 1) - pixelNo % gridHeight;
else
y = pixelNo % gridHeight;
break;
case FlowDirection.RightBottomToLeft:
y = (gridHeight -1) - pixelNo / gridWidth;
if ((pixelNo / gridWidth) % 2 == 0)
x = (gridWidth -1) - (pixelNo % gridWidth);
else
x = pixelNo % gridWidth;
break;
case FlowDirection.LeftBottomUp:
x = pixelNo / gridHeight;
if(x%2==0)
y = (gridHeight - 1) - pixelNo %gridHeight;
else
y = pixelNo % gridHeight;
break;
case FlowDirection.LeftBottomToRight:
y = (gridHeight -1) - pixelNo / gridWidth;
if ((pixelNo / gridWidth) % 2 == 0)
x = pixelNo % gridWidth;
else
x = (gridWidth - 1) - pixelNo % gridWidth;
break;
default:
throw new Exception("Wrong PixelFlow!!!");
}
DrawRectangle[...]
}