Interne Tabelle erweitern

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 21 Antworten in diesem Thema. Der letzte Beitrag () ist von tron25.

    Interne Tabelle erweitern

    Hallo,
    ich habe eine Tabelle mit 48 Spalten und 76 Zeilen, die schon mit Zahlen gefüllt ist. Nun möchte ich diese Tabelle um zwei Zeilen erweitern. Die neuen Zeilen sollen mit 0en gefüllt sein. Je nach Ausrichtung ist die Tabelle entweder 48x78 oder 78x48. Das bedeutet, dass die neuen zwei Zeilen entweder unten, links, oben oder rechts eingefügt werden. Bisher habe ich das gelöst, indem ich eine neue Tabelle erstellt habe, die schon zwei Zeilen, bzw. Spalten mehr hatte. Danach habe ich X, Y definiert und in einer Schleife die Werte kopiert. Gibt es da eine anferere Variante?

    VB.NET-Quellcode

    1. 'Die zwei neuen Zeilen werden unten angefügt.
    2. Redim Array2(47, 77)
    3. X = 0
    4. Y = 0
    5. Do Until Y >= 76
    6. Do Until X >= 48
    7. Array2(X, Y) = array1(X, Y)
    8. X += 1
    9. Loop
    10. X = 0
    11. Y += 1
    12. Loop
    13. do until y >= 78
    14. do until X >= 48
    15. Array2(X, Y) = 0
    16. X += 1
    17. loop
    18. X = 0
    19. Y += 1
    20. loop


    VB.NET-Quellcode

    1. 'Die zwei neuen Zeilen werden links angefügt.
    2. Redim Array2(77, 47)
    3. X1 = 0
    4. Y1 = 0
    5. X2 = 2
    6. Y2 = 0
    7. Do Until Y >= 47
    8. Do Until X >= 76
    9. Array2(X, Y) = array1(X, Y)
    10. X1 += 1
    11. X2 += 1
    12. Loop
    13. X1 = 0
    14. Y1 += 1
    15. X2 = 2
    16. Y2 += 1
    17. Loop
    18. x2 = 0
    19. Y2 = 0
    20. do until y >= 48
    21. do until X >= 2
    22. Array2(X2, Y2) = 0
    23. x2 += 1
    24. loop
    25. x2 = 0
    26. Y2 += 1
    27. loop


    Kann man das eleganter lösen?

    tron25 schrieb:

    Je nach Ausrichtung ist die Tabelle entweder 48x78 oder 78x48.
    Tausch nicht die Tabelle, sondern tausche die Indizes.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Es geht mir nicht um das Drehen, sondern darum, einer bestehenden Tabelle Zeilen, bzw. Spalten hinzuzufügen. Beim Drehen muß ich mit einer zweiten Tabelle arbeiten, das ist mir klar.

    Vielleicht habe ich mich etwas unglücklich ausgedrückt.

    Ich habe eine Tabelle, die mit Int-Werten gefüllt ist. Diese Tabelle wird an ein Brailledisplay gesendet. Das Display benötigt aber zwei weitere Zeilen. Wenn ich das Display allerdings virtuell um 90 Grad drehe, werden zwei zusätzliche Spalten erwartet. Die Ausgangstabelle wird zusätzlich am Bildschirm als Punktmuster angezeigt, daher wäre es nicht gut, wenn ich dieser von vorn herein zwei Zeilen bzw. Spalten verpasse.
    @tron25 Mit ReDim Preserve geht das:

    VB.NET-Quellcode

    1. Dim Array2(,) As Integer
    2. ReDim Array2(47, 77)
    3. Array2(47, 77) = 12345
    4. Label1.Text = Array2(47, 77).ToString()
    5. ReDim Preserve Array2(47, 79) ' hier nur die 2. Dimension!
    6. Label2.Text = Array2(47, 77).ToString()

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @tron25 Nicht als Einzeiler.
    Da müsstest Du ein neues Array aufbauen und den Inhalt entsprechend kopieren.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Stellt sich bei der ganzen Daten-Hin-und-Her-Schubserei die Frage, welches Grundproblem man lösen will und ob da Arrays überhaupt das sinnvollste sind.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    tron25 schrieb:

    Diese Tabelle wird an ein Brailledisplay gesendet.
    Wie ganz genau funktioniert das?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Das Display besteht aus 48x76 Stiften, die, je nach Grafik nach oben gedrückt werden, damit Blinde Personen so eine Grafik ertasten können. Jede Zeile wird aus 6 Bytes gebildet (6x8=48). Die Daten werden in 13 Blöcken, je 6 Zeilen gepackt (13x6=78). Aus diesem Grund müssen die zwei letzten Reihen leer bleiben. Wenn nun das Display um 90 Grad gedreht wird, um eine breitere Grafik besser betrachten zu können, müssen demnach die linken zwei Spalten leer bleiben.
    Ich denke ein einfacher Rotationsalgorythmus wäre hier angebracht.

    Beispiel für eine Linksdrehung 90 Grad:

    VB.NET-Quellcode

    1. 'rotation 90 grad links
    2. 'Matrix = original array
    3. dim mat As Sometype = New Sometype(Matrix.GetLength(1) - 1, Matrix.GetLength(0) - 1) {}
    4. For x As Integer = 0 To Matrix.GetLength(0) - 1
    5. For y As Integer = 0 To Matrix.GetLength(1) - 1
    6. mat(y, x) = Matrix(x, Matrix.GetLength(1) - (y + 1))
    7. Next
    8. Next
    9. Matrix = mat

    Die Natur ist bekanntermaßen knallhart, sie sortiert aus was sich nicht bewährt hat.(Harald Lesch, 2021)

    Demnach müssten wir bald dran sein...
    @tron25 Ich meinte nicht, wie das Display funktioniert, sondern wie das Daten-Array vom Rechner zum Display kommt.
    Hier erwarte ich Informationen zu:
    - externe Hardware
    - Software-Interface (Ansteuerung über DLL / eigenen Code)
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Vielen Dank für die Hilfe. Ich dachte, dass es eine Funktion gibt, die einfach eine Spalte oder Zeile einfügen kann, ohne es mit einem Hilfsarray kopieren zu müssen. Jetzt habe ich es folgendermaßen gelöst:

    VB.NET-Quellcode

    1. Public Sub HochNachQuer(Sender As Object)
    2. 'Diese Funktion dreht den Arbeitsbereich vom
    3. 'Hochformat ins Querformat.
    4. ReDim PufferArray(Hoehe, Breite)
    5. For X As Integer = 0 To PufferArray.GetUpperBound(0)
    6. For Y As Integer = 0 To PufferArray.GetUpperBound(1)
    7. PufferArray(X, Y) = PunktbildArray(Y, PunktbildArray.GetUpperBound(1) - X)
    8. Next
    9. Next
    10. ReDim PunktbildArray(Hoehe, Breite)
    11. PunktbildArray = PufferArray
    12. End Sub
    Warum ein ReDim für den PufferArray? Anstatt eine Variable auf Klassenebene zu nehmen, nimm eine lokale Variable. Auch brauchst du kein ReDim für PunktbildArray nach der Doppelschleife.
    PunktbildArray = PufferArray
    Ohne Redim die Zeile davor reicht.

    Die Sub HochNachQuer nimmt ein Argument vom Typ Object, wobei das nie in der Sub verwendet wird? Auch ist der Name schlecht gewählt, denn 1 mal angewendet, von HochNachQuer möge das Format "quer" sein, wenns es vorher "Hoch" war. Jetzt überleg mal, was passiert, wenn man PunktbildArray ein zweites mal da durchschickt. Ohne Mühe ist ersichtlich, es hat wieder die Ausgangshöhe, wie auch Breite. Bei 4 mal, sind auch die Inhalte der Indicies wieder wie original. Es findet also eine 90 Grad Drehung statt, in dem Fall nach Links, wobei auch die Dimensionen beachtet werden. Wenn nun beide Dimension gleich sind, wird nur rotiert, es ändert sich nichts am Format. Also EtwasNachLinksRotieren wäre ein passenderer Name. Noch schöner fände ich ein Array rein, das rotierte raus, so bleibt dieser Code wiederverwendbar, also aus der Sub eine Function machen.

    Aus

    0,2,3,4
    1,2,3,4
    1,2,3,4

    wird bei einmaliger Anwendung

    4,4,4
    3,3,3
    2,2,2
    0,1,1

    dann bei nochmaliger Anwendung

    4,3,2,1
    4,3,2,1
    4,3,2,0

    usw...

    Auch wäre es ratsam auf RodFromGermany's Frage zu antworten, denn vllt. hat er eine Idee wie man's besser machen kann.
    Die Natur ist bekanntermaßen knallhart, sie sortiert aus was sich nicht bewährt hat.(Harald Lesch, 2021)

    Demnach müssten wir bald dran sein...

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „Takafusa“ ()

    Neu

    Die Arbeitsfläche läßt sich vom Hoch- ins Querformat kippen. Danach kann es wieder zurücks in Hochformat gedreht werden. Das komplette Rotieren ist nicht vorgesehen.

    Die Funktion habe ich auf das Nötigste reduziert. Hier kommt sie vollständig:

    VB.NET-Quellcode

    1. Public Sub HochNachQuer(Sender As Object)
    2. 'Falls die Kamera angezeigt wird, so werden die entsprechenden
    3. 'Funktionen pausiert.
    4. KameraPause = True
    5. Do Until Not KameraBackground.IsBusy And Not KamerabildUebersetzenBackground.IsBusy
    6. Application.DoEvents()
    7. Loop
    8. 'Diese Funktion dreht den Arbeitsbereich vom
    9. 'Hochformat ins Querformat.
    10. If Grafikausrichtung = 0 Then
    11. If Sender.ToString <> "ObjektkatalogFormular" And Sender.ToString <> "KompetenzatlasFormular" Then
    12. Objektkatalogliste.Add("Querformat,1,")
    13. End If
    14. HochformatMenue.Checked = False
    15. QuerformatMenue.Checked = True
    16. Grafikausrichtung = 1
    17. ReDim PufferArray(Zeilenzahl - 1, ZeilenPunktzahl - 1)
    18. For X As Integer = 0 To PufferArray.GetUpperBound(0)
    19. For Y As Integer = 0 To PufferArray.GetUpperBound(1)
    20. PufferArray(X, Y) = PunktbildArray(Y, PunktbildArray.GetUpperBound(1) - X)
    21. Next
    22. Next
    23. PunktbildArray = PufferArray
    24. X = ZeilenPunktzahl
    25. ZeilenPunktzahl = Zeilenzahl
    26. Zeilenzahl = X
    27. '"FokusArray" wird an die neuen Masse angepasst
    28. If Fokus.ArrayLinks + Fokus.ArrayBreite > ZeilenPunktzahl Then
    29. Fokus.ArrayLinks = ZeilenPunktzahl - Fokus.ArrayBreite
    30. If Fokus.ArrayLinks < 0 Then
    31. Fokus.ArrayLinks = 0
    32. Fokus.ArrayBreite = ZeilenPunktzahl
    33. End If
    34. End If
    35. If Fokus.ArrayOben + Fokus.ArrayHoehe > Zeilenzahl Then
    36. Fokus.ArrayOben = Zeilenzahl - Fokus.ArrayHoehe
    37. If Fokus.ArrayOben < 0 Then
    38. Fokus.ArrayOben = 0
    39. Fokus.ArrayHoehe = Zeilenzahl
    40. End If
    41. End If
    42. ReDim Preserve FokusArray(Fokus.ArrayBreite - 1, Fokus.ArrayHoehe - 1)
    43. 'Wenn die Kameraanzeige nicht ausgeführt wird, so wird das
    44. 'Originalbild gedreht.
    45. If Not Kameraausgabe Then
    46. OriginalbildBitmap.RotateFlip(RotateFlipType.Rotate90FlipNone)
    47. End If
    48. X = LinkerRand
    49. LinkerRand = UntererRand
    50. UntererRand = RechterRand
    51. RechterRand = ObererRand
    52. ObererRand = X
    53. 'Nun werden die Parameter für das Layout ebenfalls gedreht.
    54. X = Seitenbreite
    55. Seitenbreite = Seitenhoehe
    56. Seitenhoehe = X
    57. SeiteEinrichten()
    58. End If
    59. KameraPause = False
    60. End Sub


    Der Objektkatalog ist eine Form, die alle Änderungen in einer Tabelle auflistet. Der Hintergrund ist der, dass einerseits alle Änderungen, unabhängig von ihrer Reihenfolge rückgängig gemacht werden können, und andererseit jemand, der eine exportierte Braillegrafikdatei erhalten hat, die Einzelschritte nachträglich verfolgen kann. Außerdem ist es so möglich, Grafiken komfortabel nachträglich ändern zu können. Wenn ich beispielsweise jemanden eine Grafik mit den olympischen Ringen zusende und dieser feststellt, dass ich versehendlich den mittleren Ring zu weit unten gezeichnet habe, so kann er den Eintrag "Mittlerer Ring" im Objektkatalog auswählen und dessen Parameter anpassen, ohne die anderen verändern zu müssen.

    Die Daten werden per Bluetooth als String an das Display gesendet. Der String besteht aus den Ascii-Werten der entsprechenden Bytes. Diese bestehen einerseits aus Kommandobytes (chr(27) & chr(2) und dem Punktmuster der Grafik.

    Neu

    Also die Methode HochNachQuer() konvertiert irgendetwas von Hoch nach Quer.
    Fehlt offsichtlich die inverse Methode QuerNachHoch() - kannste die auch noch einstellen?

    Ähm - nee ist egal.
    die gezeigte Methode hängt von 10 oder 20 externen Parametern ab (KameraBackground, KamerabildUebersetzenBackground, PufferArray, Fokus, FokusArray, LinkerRand, ObererRand..., um nur ein paar zu nennen)- das wird mir zu aufwändig, es in Ordnung zu bringen.



    Also konzentrieren auf was gefragt ist:
    Ein 2D-Array um 90° rotieren kannste nu ja.
    Kannst du auch die inverse Operation? Weil das wäre ja eine Rotation um 270°.

    Die zweite Frage war, wie zwei Zeilen einfügen: bei Hochformat oben, bei QuerFormat links
    Ist das gelöst?

    Sehr empfehlenswert - na eiglich unabdingbar - ist, für diese Operationen je eine Methode zu schreiben, der Art:

    VB.NET-Quellcode

    1. public shared Function Rotate90(arr as integer(,), forward as Boolean) as integer(,)
    2. '...

    und:

    VB.NET-Quellcode

    1. public shared Function InsertTwoLines(arr as integer(,), orientation as Orientation) as integer(,)
    2. '...

    und:

    VB.NET-Quellcode

    1. public shared Function RemoveTwoLines(arr as integer(,), orientation as Orientation) as integer(,)
    2. '...

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Neu

    Diese Funktion funktioniert. Ursprünglich ging es darum, ob man eine Spalte in ein array einfügen kann, allerdings nicht rechts oder unten. Ein Array zu erweitern funktioniert ja mit preserve. Anhand meiner Suche im Internet und der Antworten in diesem Thema habe ich eingesehen, dass ich das doch durch Kopieren mit Hilfe einer weiteren Tabelle machen muß. Die Funktion habe ich aufgelistet, um einige Unklarheiten bei der verkürzten Version zu verdeutlichen. Was ich ab Morgen machen werde, ist, einige der globalen Arrays zu entfernen und dann anzulegen, wenn sie gebraucht werden.

    Neu

    tron25 schrieb:

    Das komplette Rotieren ist nicht vorgesehen.


    Achso, ich dachte willst das "Bild" auf bzw. für das Braille drehen. Wenn das Array irgendwo danach gefüllt wird, also die Daten im Array die zum Zeitpunkt der Drehung da sind, verworfen werden, reicht auch einfach das Array neu zu instanzieren mit der entsprechenden Größe. Ich habe gedacht, deswegen willst du Zeilen hinzufügen, dann brauchste meinen Code garnet, denn der fügt nichts hinzu, sondern dreht nur. Oder bin ich jetzt auf'm Holzweg?


    Die Natur ist bekanntermaßen knallhart, sie sortiert aus was sich nicht bewährt hat.(Harald Lesch, 2021)

    Demnach müssten wir bald dran sein...

    Neu

    @tron25 Bitte beantworte doch zunächst meine Fragen aus Post #11.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Neu

    Das Display besitzt 48x76 Stifte, die in einer Lochplatte stecken und einzeln angesteuert werden können. Es gibt zwar einen Client, über den das Display angesteuert werden kann, aber ich wollte eine eigene Schnittstelle programmieren. Mein Programm, besitzt nun, dank eines Netten und geduldigen Forumers eine Bluetoothschnittstelle. Eine kurze Beschreibung meines Programms "PunktBilder" findet hier hier:</p>



    Das Programm wurde ursprünglich geschrieben, Grafiken für Blinde umzusetzen
    und diese dann auf einem Brailledrucker auszudrucken. Daher Kann das
    Programm nur ein Hoch- und ein Querformat. Das angeschlossene
    Brailledisplay dagegen, soll in alle vier Richtungen gedreht werde
    können, damit beispielsweise zwei Personen, die sich gegenüber sitzen,
    die Grafik betrachten können, ohne das Display selbst drehen zu müssen.
    Das Gerät ist etwas kleiner als ein DIN A4 Blatt.

    Das HyperFlat-4876 erwaret pro Block 40 Bytes. Die ersten zwei kündigen
    einen Befehl zum Setzen von Punkten an (chr(27) & chr(2)). Die
    nächsten zwei Bytes geben den Block an, der gesetzt werden soll. Jeder
    Block besteht aus 48x6 Punkten. Die restlichen 36 bytes geben das
    Punktmuster an, wobei jeweils 8 Punkte in einem Byte zusammengefaßt
    sind.
    Bilder
    • LKW1.png

      124,98 kB, 1.600×900, 4 mal angesehen
    • LKW2.png

      68,31 kB, 1.600×900, 4 mal angesehen
    • LKW3.png

      66,54 kB, 1.600×900, 4 mal angesehen
    • LKW4.png

      66,49 kB, 1.600×900, 4 mal angesehen
    • LKW5.png

      67,32 kB, 1.600×900, 5 mal angesehen