SSD1963 Graikfunktionen

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • SSD1963 Graikfunktionen

      New

      Hallo

      bin mal wieder am Grafikdisplay 7" mit SSD1963 am Programmieren und versuche, suche eine Funktion zu schreiben mit dem man Dreiecke und gefüllte Dreiecke Zeichnen kann. Mir fehlt aber leider der gedankliche Ansatz wie man es machen kann.

      Ja mit drei Lienien bekomme ich auch ein Dreieck erstellt. Aber verstehe noch nicht ganz wie die Funktionen von Hkipnik und Six1 richtig funktionieren womit zB ein Kreis oder eine Box gefüllt werden.

      Bräuchte ein bischen Hilfe zum verstehen der Funktionen.


      Source Code

      1. '-------------------------------------------------------------------------------
      2. 'LCD Fill Circle
      3. '-------------------------------------------------------------------------------
      4. Sub Lcd_fill_circle(byval X As Word , Byval Y As Word , Byval Radius As Word , Byval Color1 As Word)
      5. Local Xy_radius As Integer
      6. Local Zahly As Integer
      7. Local Zahlx As Integer
      8. Local Y1 As Integer
      9. Local X1 As Integer
      10. Local Y11 As Integer
      11. Local X11 As Integer
      12. Local Xy As Integer
      13. Local X2 As Word , Y2 As Word
      14. Xy_radius = Radius * Radius
      15. Y1 = -radius
      16. X1 = -radius
      17. For Zahly = Y1 To Radius
      18. Y11 = Zahly * Zahly
      19. For Zahlx = X1 To Radius
      20. X11 = Zahlx * Zahlx
      21. Xy = X11 + Y11
      22. If Xy <= Xy_radius Then
      23. X2 = X + Zahlx
      24. Y2 = Y + Zahly
      25. Call Lcd_set_pixel(x2 , Y2 , Color1)
      26. End If
      27. Next
      28. Next
      29. End Sub
      Display All

      Gruß Jörg
    • New

      Es sollte ähnlich gehen wie eine Box zu zeichnen. Ein Kreis verhält sich da anders da es einen Mittelpunkt gibt von dem aus alles berechnet werden kann.

      JOJO150272 wrote:

      Ja mit drei Linien bekomme ich auch ein Dreieck erstellt.
      Ein schönes? Bei mir wurden spitze Winkel häßlich. Entweder eine gepunktete Linie oder zu oft setzen des selben Punktes.
      Verbinde die drei Aufrufe (diagonal_linie) zu einer Funktion.
      In deiner Funktion (Dreieck(x1,y1,x2,y2,x3.y3) könnte man die darin vorhandenen Punkte zeilenweise verbinden.
    • New

      Hallo Jörg,
      ich sehe hauptsächlich zwei Anforderungen beim Füllen von Flächen:
      • Sicherzustellen, dass tatsächlich alle relevanten Punkte erfasst werden und
      • Möglichst keinen Punkt doppelt berechnenoder doppelt zu setzen, weil das unnötig Zeit kostet.
      Für den ersten Punkt ist es wichtig, eine einfach zu programmierende Entscheidung zu finden, welche Punkte dazugehören und welche nicht.
      Obwohl ein Kreis zunächst einmal recht kompliziert erscheint, ist diese Entscheidung sehr leicht umzusetzen.
      Die Punkte auf dem Kreis haben alle genau die Entfernung Radius zum Mittelpunkt, die Punkte innerhalb des Kreises haben die Entfernung <Radius.
      Und die Entfernung ergibt sich einfach aus den x- und y- Abständen (Pythagoras).
      Wenn man also vom Mittelpunkt ausgeht setzt man solange Punkte, bis der Radius größer ist und bricht dann ab.
      Dann geht man eine Zeile weiter und macht dort das Gleiche.
      Das braucht man übrigens nur für ein Viertel des Kreises zu machen, weil die anderen 3 identisch sind.
      Von daher geht das mit noch viel weniger Berechnungsaufwand, als in deiner geposteten Routine.

      Auch bei einer rechteckigen Box mit Kanten in x- und y- Richtung des Displays ist das einfach umzusetzen.
      Bei Dreiecken oder allgemein bei beliebigen Vielecken sieht das schon ganz anders aus. Besonders wenn du keine Seite hast, die genau in x- oder y-Richtung liegt.
      Ich würde horizontale oder vertikale Linien generieren, angefangen an einer der Linien zu diesem Punkt bis zur anderen.
      Die Berechnung wird jedenfalls wesentlich aufwändiger als die bei Kreisen, weil du immer die Anfangs- und Endpunkte auf den Kanten erzeugen musst.
      Du siehst, ich habe leider auch keinen einfachen Ansatz für Dreiecke, es sei denn, eine Linie liegt genau auf der x- bzw. y-Achse.
      Aber vielleicht hat ja noch jemand anderer eine zündende Idee.
    • New

      Ich habe auch noch etwas weitergemacht und nun eine Sub, die ein Polygon mit beliebig vielen Kanten zeichnen kann. Es muss nicht konvex sein, aber wenn konkav, dann keine parallele Kante zur x-Achse oder eine Hinterschneidung. Das ganz Haus ohne Fenster und Tür ist dabei ein Polygon.
      Ist schon etwas getestet, aber noch nicht so intensiv, also vielleicht gibt es noch den einen oder anderen Fehler.

      BASCOM Source Code

      1. Dim Off_x(11) , Off_y(11) As Byte
      2. Lcd_init
      3. Lcd_clear &B00_00_00_00
      4. Off_x(0) = 10 : Off_y(0) = 30 'dach
      5. Off_x(1) = 40 : Off_y(1) = 18 'kamin
      6. Off_x(2) = 41 : Off_y(2) = 3 'kamin
      7. Off_x(3) = 49 : Off_y(3) = 3 'kamin
      8. Off_x(4) = 50 : Off_y(4) = 13 'kamin
      9. Off_x(5) = 80 : Off_y(5) = 0 'dach
      10. Off_x(6) = 150 : Off_y(6) = 30 'dach
      11. Off_x(7) = 130 : Off_y(7) = 30 'mauern
      12. Off_x(8) = 129 : Off_y(8) = 60 'mauern
      13. Off_x(9) = 31 : Off_y(9) = 60 'mauern
      14. Off_x(10) = 30 : Off_y(10) = 30 'mauern
      15. Lcd_fill_polygon Off_x() , Off_y() , 10 , 2
      16. Off_x(0) = 50 : Off_y(0) = 30
      17. Off_x(1) = 59 : Off_y(1) = 30
      18. Off_x(2) = 59 : Off_y(2) = 39
      19. Off_x(3) = 50 : Off_y(3) = 39
      20. Lcd_fill_polygon Off_x() , Off_y() , 3 , 2
      21. Off_x(0) = 61 : Off_y(0) = 30
      22. Off_x(1) = 70 : Off_y(1) = 30
      23. Off_x(2) = 70 : Off_y(2) = 39
      24. Off_x(3) = 61 : Off_y(3) = 39
      25. Lcd_fill_polygon Off_x() , Off_y() , 3 , 2
      26. Off_x(0) = 50 : Off_y(0) = 41
      27. Off_x(1) = 59 : Off_y(1) = 41
      28. Off_x(2) = 59 : Off_y(2) = 50
      29. Off_x(3) = 50 : Off_y(3) = 50
      30. Lcd_fill_polygon Off_x() , Off_y() , 3 , 2
      31. Off_x(0) = 61 : Off_y(0) = 41
      32. Off_x(1) = 70 : Off_y(1) = 41
      33. Off_x(2) = 70 : Off_y(2) = 50
      34. Off_x(3) = 61 : Off_y(3) = 50
      35. Lcd_fill_polygon Off_x() , Off_y() , 3 , 2
      36. Off_x(0) = 90 : Off_y(0) = 30
      37. Off_x(1) = 110 : Off_y(1) = 30
      38. Off_x(2) = 110 : Off_y(2) = 59
      39. Off_x(3) = 90 : Off_y(3) = 59
      40. Lcd_fill_polygon Off_x() , Off_y() , 3 , 2
      41. Off_x(0) = 70 : Off_y(0) = 10
      42. Off_x(1) = 90 : Off_y(1) = 10
      43. Off_x(2) = 90 : Off_y(2) = 22
      44. Off_x(3) = 70 : Off_y(3) = 22
      45. Lcd_fill_polygon Off_x() , Off_y() , 3 , 1
      46. Lcd_fill_circle 180 , 15 , 15 , 2
      47. Off_x(0) = 176 : Off_y(0) = 30
      48. Off_x(1) = 184 : Off_y(1) = 30
      49. Off_x(2) = 185 : Off_y(2) = 55
      50. Off_x(3) = 187 : Off_y(3) = 60
      51. Off_x(4) = 173 : Off_y(4) = 60
      52. Off_x(5) = 175 : Off_y(5) = 55
      53. Lcd_fill_polygon Off_x() , Off_y() , 5 , 1
      54. Sub Lcd_fill_polygon(array_x()as Byte , Array_y()as Byte , Byval Max_index As Byte , Byval Pixval As Byte) 'Sub zur Erzeugung von konvexen Polygonen mit beliebiger Anzahl an Punkten
      55. 'mit Einschränkungen gehen auch konkave (es dürfen in x-Richtung keine Hinterschneidungen oder parallel Kanten sein
      56. Local Temp As Byte
      57. Local Min_x As Byte
      58. Local Index_dir As Integer
      59. Local Start_index As Byte
      60. Local End_index As Byte
      61. Local Next_index As Byte
      62. Local Prev_index As Byte
      63. Local Next_gradient As Single
      64. Local Prev_gradient As Single
      65. Local Line_1_x As Single
      66. Local Line_1_y As Single
      67. Local Line_2_x As Single
      68. Local Line_2_y As Single
      69. Local L_1_x As Byte
      70. Local L_1_y As Byte
      71. Local L_2_x As Byte
      72. Local L_2_y As Byte
      73. Min_x = 255
      74. For Temp = 0 To Max_index 'finde den kleinsten x_wert
      75. 'Print Array_x(temp) ; ":" ; Array_y(temp)
      76. If Array_x(temp) < Min_x Then
      77. Start_index = Temp
      78. Min_x = Array_x(temp)
      79. End If
      80. Next Temp
      81. If Start_index < Max_index Then Next_index = Start_index + 1 Else Next_index = 0 'nächster Punkt
      82. If Start_index > 0 Then Prev_index = Start_index - 1 Else Prev_index = Max_index 'vorhergehender Punkt
      83. If Array_x(start_index) = Array_x(next_index) Then 'feststellen, ob bei min_x eine vertikale Linie zum nächsten Punkt ist
      84. Lcd_line Array_x(start_index) , Array_y(start_index) , Array_x(next_index) , Array_y(next_index) , Pixval
      85. End_index = Next_index
      86. Index_dir = -1
      87. Elseif Array_x(start_index) = Array_x(prev_index) Then 'feststellen, ob bei min_x eine vertikale Linie zum nächsten Punkt ist
      88. Lcd_line Array_x(start_index) , Array_y(start_index) , Array_x(prev_index) , Array_y(prev_index) , Pixval
      89. End_index = Prev_index
      90. Index_dir = 1
      91. Else
      92. Lcd_pset Array_x(start_index) , Array_y(start_index) , Pixval
      93. End_index = Start_index
      94. Index_dir = 0
      95. End If
      96. Next_index = Start_index
      97. Prev_index = End_index
      98. Do
      99. If Start_index = Next_index Then 'falls wir den nachfolgenden Punkt erreicht haben, den nächsten danach finden
      100. If Index_dir = 1 Then
      101. If Start_index < Max_index Then Next_index = Start_index + 1 Else Next_index = 0
      102. Else
      103. If Start_index > 0 Then Next_index = Start_index - 1 Else Next_index = Max_index
      104. End If
      105. Next_gradient = Calc_gradient(array_x(start_index) , Array_y(start_index) , Array_x(next_index) , Array_y(next_index)) 'Steigung zum nächsten Startpunkt
      106. Line_1_x = Array_x(start_index)
      107. Line_1_y = Array_y(start_index)
      108. End If
      109. If End_index = Prev_index Then 'falls wir den vorhergehenden Punkt erreicht haben, den nächsten davor finden
      110. If Index_dir = 1 Then
      111. If End_index > 0 Then Prev_index = End_index - 1 Else Prev_index = max_index
      112. Else
      113. If End_index < max_index Then Prev_index = End_index + 1 Else Prev_index = 0
      114. End If
      115. Prev_gradient = Calc_gradient(array_x(end_index) , Array_y(end_index) , Array_x(prev_index) , Array_y(prev_index)) 'Steigung zum nächsten Endpunkt finden
      116. Line_2_x = Array_x(end_index)
      117. Line_2_y = Array_y(end_index)
      118. End If
      119. Do
      120. Line_1_x = Line_1_x + 1 'startpunkt der nächsten linie
      121. Line_1_y = Line_1_y + Next_gradient
      122. Line_2_x = Line_2_x + 1 'endpunkt de nächsten Linie
      123. Line_2_y = Line_2_y + Prev_gradient
      124. L_1_x = Line_1_x
      125. L_1_y = Round(line_1_y)
      126. L_2_x = Line_2_x
      127. L_2_y = Round(line_2_y)
      128. Lcd_line L_1_x , L_1_y , L_2_x , L_2_y , Pixval
      129. 'Waitms 10
      130. Loop Until L_1_x = Array_x(next_index) Or L_2_x = Array_x(prev_index) 'abbrechen, wenn an einer Seite der nächste Punkt erreicht wurde
      131. If Index_dir = 1 Then
      132. If Prev_index > 0 Then Temp = Prev_index - 1 Else Temp = Max_index
      133. Else
      134. If Prev_index < Max_index Then Temp = Prev_index + 1 Else Temp = 0
      135. End If
      136. If Array_x(next_index) = Array_x(prev_index) And Temp = Next_index Or Next_index = Prev_index Then Exit Do 'wir sind fertig
      137. If L_1_x = Array_x(next_index) Then Start_index = Next_index
      138. If L_2_x = Array_x(prev_index) Then End_index = Prev_index
      139. Loop
      140. End Sub
      141. Function Calc_gradient(x1 , Y1 , X2 , Y2) As Single
      142. Local X As Single
      143. Local Y As Single
      144. X = X2 - X1
      145. Y = Y2 - Y1
      146. Calc_gradient = Y / X
      147. End Function
      Display All
      Polygon.jpg
    • New

      Hallo,

      erstmal Danke für die vielen Beiträge.

      Bin gerade am durchschauuen und versuchen die Funktionen von Franz zu verstehen.

      @Franz

      Beim übernehmen des Codes ist mir aufgefallen das der Error 263, Array index out of range auftrat. Ok bei deinen Arrays beginnst du bei 0, komisch bei mir Version 2.0.8.3 geht es mit 1 los. Welche Version verwendest Du Franz ?

      In der Sub Lcd_fill_polygon(array_x()as Byte , Array_y()as Byte , Byval Max_index As Byte , Byval Pixval As Byte) verwendest Du Pixval, für was ist dise Variable ?

      Auch fehlen mir zum probieren die Funktionen:
      - Lcd_line Array_x(start_index) , Array_y(start_index) , Array_x(next_index) , Array_y(next_index) , Pixval
      - Lcd_pset Array_x(start_index) , Array_y(start_index) , Pixval

      Könntest Du Sie mir zur Verfügung stellen?

      @Pluto25
      Ja so habe ich mir bis jetzt geholfen indem ich im Dreieck Linie für Linie gezeichnet habe, sah nicht immer so gut aus hat aber seinen Zweck so leidlich erfüllt.

      @'hkipnik'

      Sieht recht gut aus, auch dir währe ich sehr dankbar für einige Grafikfunktionen.



      Auch wäre ich für weitere Grafikfunktionen sehr dankbar, bin ständig am Versuchen diese zu verstehen und Verbesserungen an meinen Programmen durchzuführen.

      Gruß Jörg
    • New

      BASCOM Source Code

      1. Declare Sub Lcd_triangle(byval X_a As Word , Byval Y_a As Word , Byval X_b As Word , Byval Y_b As Word , Byval X_c As Word , Byval Y_c As Word , Byval Color As Word )
      2. Declare Sub Lcd_fill_triangle(byval X_a As Word , Byval Y_a As Word , Byval X_b As Word , Byval Y_b As Word , Byval X_c As Word , Byval Y_c As Word , Byval Color As Word )
      3. Lcd_fill_triangle 70 , 120 , 130 , 150 , 130 , 90 , Green
      4. Lcd_fill_triangle 130 , 90 , 190 , 90 , 160 , 30 , Red
      5. Lcd_fill_triangle 190 , 150 , 250 , 120 , 190 , 90 , Yellow
      6. Lcd_fill_triangle 130 , 150 , 190 , 150 , 160 , 210 , Blue
      7. Lcd_triangle 70 , 120 , 130 , 150 , 130 , 90 , Green
      8. Lcd_triangle 130 , 90 , 190 , 90 , 160 , 30 , Red
      9. Lcd_triangle 190 , 150 , 250 , 120 , 190 , 90 , Yellow
      10. Lcd_triangle 130 , 150 , 190 , 150 , 160 , 210 , Blue
      11. '*******************************************************************************
      12. 'Draw Triangle
      13. '*******************************************************************************
      14. '
      15. ' Xa-Ya Xb-Yb
      16. ' ________ Xc-Yc
      17. ' \ / /\
      18. ' \ / / \
      19. ' \ / / \
      20. ' Xc-Yc ------
      21. ' Xa-Ya Xb-Yb
      22. '*******************************************************************************
      23. Sub Lcd_triangle(byval X_a As Word , Byval Y_a As Word , Byval X_b As Word , Byval Y_b As Word , Byval X_c As Word , Byval Y_c As Word , Byval Color As Word)
      24. Lcd_line X_a , Y_a , X_b , Y_b , 1 , Color
      25. Lcd_line X_b , Y_b , X_c , Y_c , 1 , Color
      26. Lcd_line X_c , Y_c , X_a , Y_a , 1 , Color
      27. End Sub
      28. '*******************************************************************************
      29. 'Draw Fill Triangle
      30. '*******************************************************************************
      31. '
      32. ' Xa-Ya Xb-Yb
      33. ' ________ Xc-Yc
      34. ' \ / /\
      35. ' \ / / \
      36. ' \ / / \
      37. ' Xc-Yc ------
      38. ' Xa-Ya Xb-Yb
      39. '*******************************************************************************
      40. Sub Lcd_fill_triangle(byval X_a As Word , Byval Y_a As Word , Byval X_b As Word , Byval Y_b As Word , Byval X_c As Word , Byval Y_c As Word , Byval Color As Word )
      41. Local X As Word , X_diff As Single , Y_diff As Single , Pos As Word
      42. Local X_factor As Single , Y_pos As Word , Pen_count As Word
      43. Local Zx_diff As Single , Zx_factor As Single
      44. Local Zy_diff As Single , Zy_factor As Single , Zy As Word , Xyz As Word
      45. Local Zy1_diff As Single , Zy1_factor As Single , Zy1 As Word , Xyz1 As Word
      46. Pen_count = 0
      47. Pos = 0
      48. Y_diff = Y_b - Y_a
      49. X_diff = X_b - X_a
      50. If Y_a < Y_c Then 'Yc greater Ya YC down
      51. Zx_diff = X_c - X_a 'Xdiff left side
      52. Xyz = Abs(zx_diff)
      53. Zy_diff = Y_a - Y_c 'Ydiff Ya Yc
      54. Zy_factor = Zy_diff / Zx_diff
      55. Zy_factor = Abs(zy_factor)
      56. Zx_diff = X_b - X_c
      57. Zy1_diff = Y_b - Y_c
      58. Zy1 = Abs(zy1_diff)
      59. Zy1_factor = Zy1_diff / Zx_diff
      60. Zy1_factor = Abs(zy1_factor)
      61. Xyz1 = 1
      62. X_factor = Y_diff / X_diff 'Xfactor Base line
      63. For X = X_a To X_b
      64. Y_diff = Pos * X_factor 'find Y Start Pos
      65. Y_pos = Y_diff
      66. Y_pos = Y_pos + Y_a ' + Y Base
      67. If Pen_count <= Xyz Then 'Left side
      68. Zy_diff = Pos * Zy_factor
      69. Zy = Y_pos + Zy_diff
      70. Zy1_diff = Y_a - Y_pos
      71. Zy = Zy + Zy1_diff
      72. Lcd_line X , Y_pos , X , Zy , 1 , Color 'muß auf das Programm abgestimmt werden
      73. Incr Pen_count
      74. Else 'Right side
      75. Zy_diff = Xyz1 * Zy1_factor
      76. Zy = Zy1 - Zy_diff
      77. Zy = Y_pos + Zy
      78. Zy1_diff = Y_b - Y_pos
      79. Zy = Zy + Zy1_diff
      80. Lcd_line X , Y_pos , X , Zy , 1 , Color
      81. Incr Xyz1
      82. End If
      83. Incr Pos
      84. Next X
      85. Else 'Yc smaller Ya YC up
      86. Zx_diff = X_c - X_a
      87. Xyz = Abs(zx_diff)
      88. Zy_diff = Y_c - Y_a
      89. Zy_factor = Zy_diff / Zx_diff
      90. Zy_factor = Abs(zy_factor)
      91. Zx_diff = X_b - X_c
      92. Zy1_diff = Y_b - Y_c
      93. Zy1 = Abs(zy1_diff)
      94. Zy1_factor = Zy1_diff / Zx_diff
      95. Zy1_factor = Abs(zy1_factor)
      96. Xyz1 = 1
      97. X_factor = Y_diff / X_diff
      98. For X = X_a To X_b
      99. Y_diff = Pos * X_factor 'find Y Start Pos
      100. Y_pos = Y_diff
      101. Y_pos = Y_pos + Y_a 'Base
      102. If Pen_count <= Xyz Then 'Left side
      103. Zy_diff = Pos * Zy_factor
      104. Zy = Y_pos - Zy_diff
      105. Zy1_diff = Y_a - Y_pos
      106. Zy = Zy + Zy1_diff
      107. Lcd_line X , Y_pos , X , Zy , 1 , Color
      108. Incr Pen_count
      109. Else 'Right side
      110. Zy_diff = Xyz1 * Zy1_factor
      111. Zy = Zy1 - Zy_diff
      112. Zy = Y_pos - Zy
      113. Zy1_diff = Y_b - Y_pos
      114. Zy = Zy + Zy1_diff
      115. Lcd_line X , Y_pos , X , Zy , 1 , Color
      116. Incr Xyz1
      117. End If
      118. Incr Pos
      119. Next X
      120. End If
      121. End Sub
      Display All