Bresenham Algorythmus in bascom übersetzen

Bonze

Neues Mitglied
16. Jan. 2010
516
0
0
Altenkirchen (Pfalz)
Sprachen
  1. BascomAVR
um endlich mal 2 punkte miteinander verbinden zu können auf meinem lcd brauch ich den Bresenham algo, jedoch lässt dieser sich nicht so einfach in bascom übersetzen, bzw dachte ich eigentlich das es einfacher gehn muss,
habs eigentlich schon soweit, jedoch bringt mir bascom immer nen fehler

Code:
Sub Lcd_line(byval Xpos1 As Word , Byval Ypos1 As Word , Byval Xpos2 As Word , Byval Ypos2 As Word)
 REM Bresenham-Algorithmus für eine Linie in einem beliebigen Oktanten in Pseudo-Basic
 Local Dx As Long
 Local Dy As Long
 Local Adx As Long
 Local Ady As Long
 Local Sdx As Single
 Local Sdy As Single
 Local Pdy As Word
 Local Pdx As Word
 Local Ddx As Word
 Local Ddy As Word
 Local Es As Word
 Local El As Word
 Local I As Word
 Local X As Word
 Local Y As Word
 Local Fehler As Byte

 Dx = Xpos2 - Xpos1
 Dy = Ypos2 - ypos1

 REM Initialisierungen
 Adx = Abs(dx)
 Ady = Abs(dy)                                              ' Absolutbetraege Distanzen
[I] Sdx = Sgn(dx)
 sdy = SGN(dy) ' Signum Distanzen[/I]

 IF adx > ady THEN
   ' x ist schnelle Richtung
   Pdx = Sdx:pdy = 0   ' pd. ist Parallelschritt
   Ddx = Sdx : Ddy = Sdy                                    ' dd. ist Diagonalschritt
   Es = Ady : El = Adx                                      ' Fehlerschritte schnell, langsam
 ELSE
   ' y ist schnelle Richtung
   Pdx = 0 : Pdy = Sdy                                      ' pd. ist Parallelschritt
   Ddx = Sdx : Ddy = Sdy                                    ' dd. ist Diagonalschritt
   Es = Adx : El = Ady                                      ' Fehlerschritte schnell, langsam
 END IF

 X = Xpos1
 Y = Ypos1
 Call Lcd_set_pixel(x , Y , White)
 fehler = el/2

 REM Pixelschleife: immer ein Schritt in schnelle Richtung, hin und wieder auch einer in langsame
 FOR i=1 TO el          ' el gibt auch Anzahl der zu zeichnenden Pixel an
    REM Aktualisierung Fehlerterm
    fehler = fehler - es
    IF fehler < 0 THEN
       fehler = fehler + el ' Fehlerterm wieder positiv (>=0) machen
       REM Schritt in langsame Richtung
       x = x + ddx: y = y + ddy ' Diagonalschritt
    ELSE
       REM Schritt in schnelle Richtung
       x = x + pdx: y = y + pdy ' Parallelschritt
    END IF
    Call Lcd_set_pixel(x , Y , White)
 Next
End Sub

weiss jemand vielleicht warum ich in der markierten zeile nen fehler Code 63 bekomme, Integer or Long expected? habs doch oben definiert,.
 
So geht es auch, es braucht keine Single oder Long-Variablen.

Code:
Dim Dx As Integer
Dim Dy As Integer
Dim Adx As Word
Dim Ady As Word
Dim Sdx As Integer
Dim Sdy As Integer
Dim Pdx As Word
Dim Pdy As Word
Dim Ddx As Word
Dim Ddy As Word
Dim Es As Word
Dim El As Word
Dim Fehler As Integer
Dim I As Word

Gl_line:
Rem Bresenham-Algorithmus für eine Linie in einem beliebigen Oktanten in Pseudo-Basic
 Dx = Gl_x2 - Gl_x1
 Dy = Gl_y2 - Gl_y1
Rem Initialisierungen
 Adx = Abs(dx)
 Ady = Abs(dy)                                              ' Absolutbetraege Distanzen
 'Sdx = Sgn(dx)
 'Sdy = Sgn(dy)                              ' Signum Distanzen
Select Case Dx
   Case Is > 0
      Sdx = 1
   Case Is < 0
      Sdx = -1
   Case 0
      Sdx = 0
End Select

Select Case Dy
   Case Is > 0
      Sdy = 1
   Case Is < 0
      Sdy = -1
   Case 0
      Sdy = 0
End Select



 If Adx > Ady Then
   ' x ist schnelle Richtung
   Pdx = Sdx
   Pdy = 0                                                  ' pd. ist Parallelschritt
   Es = Ady
   El = Adx                                                 ' Fehlerschritte schnell, langsam
 Else
   ' y ist schnelle Richtung
   Pdx = 0
   Pdy = Sdy                                                ' pd. ist Parallelschritt
   Es = Adx
   El = Ady                                                 ' Fehlerschritte schnell, langsam
 End If
 Ddx = Sdx
 Ddy = Sdy                                                  ' dd. ist Diagonalschritt

 Gl_x = Gl_x1
 Gl_y = Gl_y1
 Gosub Gl_setdot
 Fehler = El / 2
Rem Pixelschleife: immer ein Schritt in schnelle Richtung, hin und wieder auch einer in langsame
 For I = 1 To El                                            ' el gibt auch Anzahl der zu zeichnenden Pixel an
Rem Aktualisierung Fehlerterm
    Fehler = Fehler - Es
    If Fehler < 0 Then
       Fehler = Fehler + El                                 ' Fehlerterm wieder positiv (>=0) machen
Rem Schritt in langsame Richtung
       Gl_x = Gl_x + Ddx : Gl_y = Gl_y + Ddy                ' Diagonalschritt
    Else
Rem Schritt in schnelle Richtung
       Gl_x = Gl_x + Pdx : Gl_y = Gl_y + Pdy                ' Parallelschritt
    End If
    Gosub Gl_setdot
 Next
Return
 
mhh dann bekomme ich bei dx, dy schon nen fehler "Source variable does not match the target variable"
meine koordinaten sind beide Word,. also word-word = integer
 
Dimensioniere mal die Variablen global, welche von der "Sub Lcd_line" benutzt werden, Xpos1... usw.
 
die meinst du das? nocheinmal komplett mit dim dimensionieren?

hab deine version mal eingebaut, da sind die variablen ja schon global,.
 
mh man sollte schon 1 und l untercheiden können,.
apropo irgendwie hat er bei mir Rem nicht so gut vertragen, das muss immer alleine in ner zeile stehen,.
so gehts auch endlich :D
Code:
Sub Lcd_line(byval Gl_x1 As Word , Byval Gl_y1 As Word , Byval Gl_x2 As Word , Byval Gl_y2 As Word , Byval Color As Word)

Dim Dx As Integer
Dim Dy As Integer
Dim Adx As Word
Dim Ady As Word
Dim Sdx As Integer
Dim Sdy As Integer
Dim Pdx As Word
Dim Pdy As Word
Dim Ddx As Word
Dim Ddy As Word
Dim Es As Word
Dim El As Word
Dim Fehler As Integer
Dim I As Word
Dim Gl_x As Word
Dim Gl_y As Word
Rem Bresenham-Algorithmus für eine Linie in einem beliebigen Oktanten in Pseudo-Basic
Dx = Gl_x2 - Gl_x1
Dy = Gl_y2 - Gl_y1
Rem Initialisierungen
Adx = Abs(dx)
Ady = Abs(dy)                                               ' Absolutbetraege Distanzen
'Sdx = Sgn(dx)
'Sdy = Sgn(dy) ' Signum Distanzen
Select Case Dx
   Case Is > 0
      Sdx = 1
   Case Is < 0
      Sdx = -1
   Case 0
      Sdx = 0
End Select

Select Case Dy
   Case Is > 0
      Sdy = 1
   Case Is < 0
      Sdy = -1
   Case 0
      Sdy = 0
End Select
If Adx > Ady Then                                           ' x ist schnelle Richtung
   Pdx = Sdx
   Pdy = 0                                                  ' pd. ist Parallelschritt
   Es = Ady
   El = Adx                                                 ' Fehlerschritte schnell, langsam
Else                                                        ' y ist schnelle Richtung
   Pdx = 0
   Pdy = Sdy                                                ' pd. ist Parallelschritt
   Es = Adx
   El = Ady                                                 ' Fehlerschritte schnell, langsam
End If
Ddx = Sdx
Ddy = Sdy                                                   ' dd. ist Diagonalschritt
Gl_x = Gl_x1
Gl_y = Gl_y1
Call Lcd_set_pixel(gl_x1 , Gl_y1 , Color)
Fehler = El / 2                                             ' Pixelschleife: immer ein Schritt in schnelle Richtung, hin und wieder auch einer in langsame
For I = 1 To El                                             ' el gibt auch Anzahl der zu zeichnenden Pixel an
'Aktualisierung Fehlerterm
   Fehler = Fehler - Es
   If Fehler < 0 Then
      Fehler = Fehler + El                                  ' Fehlerterm wieder positiv (>=0) machen
'Schritt in langsame Richtung
      Gl_x = Gl_x + Ddx : Gl_y = Gl_y + Ddy                 ' Diagonalschritt
   Else                                                     ' Schritt in schnelle Richtung
      Gl_x = Gl_x + Pdx : Gl_y = Gl_y + Pdy                 ' Parallelschritt
   End If
   Call Lcd_set_pixel(gl_x , Gl_y , Color)
Next
End Sub
 
Korrektur:
Das mit dem Dim .... wird nicht funktionieren, habe es gerade getestet.
Mit den Parametern, welche du bei Sub Lcd_line() übergibst, kannst du nur in dieser Sub arbeiten. Willst du z.B. mit Gosub in einer weiteren Sub mit diesen Variablen arbeiten, musst du die in der ersten Sub in globalen Variablen sichern. So mache ich es in meinem Programm auch. Wenn du Variablen mit Dim definierst, wie vorgeschlagen, sind zwar die Fehler weg aber die Variablen bleiben immer auf 0.
 
Hat sich Dein Problem damit geklärt, oder?
 
jepp, funktioniert auf jedenfall,.
schön wär dann noch wenn die kreis ansteuerung funktionieren würde, has genauso gemacht wie hier , bekomme jedoch nur vereinzelte punkte auf dem display angezeigt,.)
Code:
Sub Lcd_circle(byval Xpos As Word , Byval Ypos As Word , Byval R As Word , Byval Color As Word)
 Local Xmittel As Word
 Local Xmittelpx As Word
 Local Xmittelmx As Word
 Local Xmittelpy As Word
 Local Xmittelmy As Word
 Local Ymittel As Word
 Local Ymittelpy As Word
 Local Ymittelmy As Word
 Local Ymittelpx As Word
 Local Ymittelmx As Word
 Local Dx As Integer
 Local Dy As Integer
 Local Fehler As Word
 'R As Word

Rem Bresenham-Algorithmus für einen Achtelkreis in Pseudo-Basic
Rem gegeben seien r, xmittel, ymittel
Rem Initialisierungen für den ersten Oktanten
 Xpos = R
 Ypos = 0
 Fehler = R
Rem "schnelle" Richtung ist hier y!
Xmittel = Xmittel + Xpos
Ymittel = Ymittel + Ypos

 Call Lcd_set_pixel(xmittel , Ymittel , Color)

Rem Pixelschleife: immer ein Schritt in schnelle Richtung, hin und wieder auch einer in langsame
 While Ypos < Xpos
Rem Schritt in schnelle Richtung
    Dy = Ypos * 2
    Dy = Dy + 1                                             'REM bei Assembler-Implementierung *2 per Shift
    Ypos = Ypos + 1
    Fehler = Fehler - dy
    If Fehler < 0 Then
Rem Schritt in langsame Richtung (hier negative x-Richtung)
       Dx = 1 - Xpos
       Dx = Dx * 2                                          'REM bei Assembler-Implementierung *2 per Shift
       Xpos = Xpos - 1
       Fehler = Fehler - dx
    End If
    Xmittelpx = Xmittel + Xpos
    Xmittelpy = Xmittel + Ypos
    Xmittelmx = Xmittel - Xpos
    Xmittelmy = Xmittel - Ypos
    Ymittelpy = Ymittel + Ypos
    Ymittelpx = Ymittel + Xpos
    Ymittelmx = Ymittel - Xpos
    Ymittelmy = Ymittel - Ypos
    Call Lcd_set_pixel(xmittelpx , Ymittelpx , Color)
    Call Lcd_set_pixel(xmittelmx , Ymittelpy , Color)
    Call Lcd_set_pixel(xmittelmx , Ymittelmy , Color)
    Call Lcd_set_pixel(xmittelpx , Ymittelmy , Color)
    Call Lcd_set_pixel(xmittelpy , Ymittelpx , Color)
    Call Lcd_set_pixel(xmittelmy , Ymittelpx , Color)
    Call Lcd_set_pixel(xmittelmy , Ymittelmx , Color)
    Call Lcd_set_pixel(xmittelpy , Ymittelmx , Color)
 Wend

End Sub
 

Anhänge

  • linie2.jpg
    linie2.jpg
    151,3 KB · Aufrufe: 17

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)