Die Inkremente für x und y entsprechdend der Größe der Vektorkomponenten wählen. Der größere Wert ist 1 der kleinere ensprechend geringer.
Das erfordert eine höhere Auflösung bei Lx und Ly. Ausgegeben wid dann nur der "ganzzahlige" Teil.
Manfred
in der tat sieht das so auf das ist aber voll blööd. äähm meinst das das rein softwaretechnisch zu lösen ist? man müsste mal in eine turbo pascal unit reinschauen wie die das gemacht haben... aber damit nimmt man ja den reiz der ganzen geschichte. jemand anderes noch eine idee???
Die Inkremente für x und y entsprechdend der Größe der Vektorkomponenten wählen. Der größere Wert ist 1 der kleinere ensprechend geringer.
Das erfordert eine höhere Auflösung bei Lx und Ly. Ausgegeben wid dann nur der "ganzzahlige" Teil.
Manfred
Hä *kopfkratz* langsam jetzt bitte. Soll ich also den wertebereich erweitern und dann ins verhältniss stellen? *fragend guck*
Hallo,
ich hab in der Mittagspause mal schnell in Pseudocode skizziert,
wie ich mir so eine Line-Routine vorstelle.
Müsste eigentlich funktionieren.
Die Linien sind allerdings noch nicht balanciert,
da war noch ein Trick nötig, der mir jetzt auf
die Schnelle nicht einfällt.
Schau dirs halt mal an...Code:;Drawline in Pseudocode. ;----------------------- ;Übergeben werden die Start- und Endpunkte der Linie xs,ys und ys,ye ;Die Routine braucht nur Addition /Subtrktion, kommt ohne Multiplikation / Division aus. ;Alle Variable könne Byte sein. ;Kann problemlos und einfach in Assembler kodiert werden. Drawline(xs,ys,ys,ye) ;Längen für x und y ausrechnen xlen=xs-xe ylen=ys-ye ;Schrittrichtung für x und Y festlegen if xlen>=0 then xa=1 else xa=-1 if ylen>=0 then ya=1 else ya=-1 ;wenn xlänge grösser ist, dann laufen wir an der X-Achse entlang ; ansonsten an der Y-Achse if abs(xlen) < abs(ylen) then goto walky walkx: temp=xlen do portx=xs porty=ys xs=xs+xa :immer einen Schritt in x-Richtung weiter temp=temp-ylen ;Schritt in Y-Richtung nötig ? if temp<=0 then ;wenn <=0 dann ja temp=temp+xlen ; ys=ys+ya ;Schritt in Y-Richtung endif loop until xs=xe ;Wiederholen bis Ende der Linie Return ;Ende sub WalkY: temp=ylen do portx=xs porty=ys ys=ys+ya temp=temp-xlen if temp<0 then temp=temp+ylen xs=xs+xa endif loop until ys=ye return
Ich denke immer noch über die Hardwarelösung nach,
wo die Linie auf dem Scope mittels zweier Integratoren
automatisch gezogen wird.
Gruß Jan
Wenn dx= 12 und dy = 3 ist, dann kann man in jedem Schritt x um 1 erhöhen und y um 1/4 erhöhen und erreicht bei angepasster Schrittweite gleichzeitig den Zielpunkt.
Die Ausgabewerte sollten für den D/A Wandler ganzzahlig sein, die intere Berechnung benötigt dafür eine höhere Auflösung.
Manfred
So habe mal versucht den pseudocode anzupassen, viel war ja nicht mehr zu machen... Es scheint ein bisschen buggy zu sein. Hat jemand anderes schon die hardware nachgebaut???
Code:$regfile = "m128def.dat" $crystal = 16000000 '#########Variablen Line Funktion Dim Xlen As Long Dim Ylen As Long Dim Xa As Long Dim Ya As Long Dim Temp As Long '################################# Declare Sub Drawline(byval Xs As Byte , Byval Ys As Byte , Byval Xe As Byte , Byval Ye As Byte) Config Porta = Output Config Portc = Output Config Portf = Output Z Alias Portf.1 Z = 1 ' dunkel Do Call Drawline(0 , 0 , 100 , 100) Waitms 1 Loop End 'Drawline in Pseudocode. ';----------------------- ' ';Übergeben werden die Start- und Endpunkte der Linie xs,ys und ys,ye ' ';Die Routine braucht nur Addition /Subtrktion, kommt ohne Multiplikation / Division aus. ';Alle Variable könne Byte sein. ';Kann problemlos und einfach in Assembler kodiert werden. Sub Drawline(xs As Byte , Ys As Byte , Xe As Byte , Ye As Byte) ';Längen für x und y ausrechnen xlen=xs-xe ylen=ys-ye ';Schrittrichtung für x und Y festlegen if xlen>=0 then xa=1 else xa=-1 if ylen>=0 then ya=1 else ya=-1 ';wenn xlänge grösser ist, dann laufen wir an der X-Achse entlang '; ansonsten an der Y-Achse If Xlen < 0 Then Xlen = Xlen * -1 If Ylen < 0 Then Xlen = Xlen * -1 If Xlen < Ylen Then Goto Walky walkx: Z = 0 'licht einschalten temp=xlen do Porta = Xs Portc = Ys Waitus 1 Xs = Xs + Xa ':immer einen Schritt in x-Richtung weiter Temp = Temp - ylen ';Schritt in Y-Richtung nötig ? If Temp <= 0 Then ';wenn <=0 dann ja Temp = Temp + Xlen '; Ys = Ys + Ya ';Schritt in Y-Richtung endif Loop Until Xs = Xe ';Wiederholen bis Ende der Linie Goto Endofsub WalkY: Z = 0 temp=ylen do Porta = Xs Portc = Ys Waitus 1 ys=ys+ya temp=temp-xlen if temp<0 then temp=temp+ylen xs=xs+xa endif loop until ys=ye Endofsub: Z = 1 'und wieder aus End Sub
Hallo Sebastian,
ich habe deinen Code noch mal überarbeitet.
Sollte jetzt funktionieren.
Hauptproblem war das Bascom die Byte-Variablen nicht
als vorzeichenbehaftete Zahlen betrachten kann.
Deshalb habe ich es auf Integer umgeändert.
Probier es doch mal aus,und gib Bescheid, was passiert.
Müsste ein Dreieck angezeigt werden.
Gruß Jan
Code:$regfile = "m128def.dat" $crystal = 16000000 '#########Variablen Line Funktion Dim Xlen As Integer Dim Ylen As Integer Dim Xa As Integer Dim Ya As Integer Dim Temp As Integer '################################# Declare Sub Drawline(byval Xs As Integer , Byval Ys As Integer , Byval Xe As Integer , Byval Ye As Integer) Config Porta = Output Config Portc = Output Config Portf = Output Z Alias Portf.1 Z = 1 ' dunkel Do Call Drawline(0 , 0 , 100 , 80 ) Call Drawline(100 , 80 , 22 , 33) Call Drawline(22 , 33 , 0 , 0) Waitms 1 Loop End Sub Drawline(xs As Integer , Ys As Integer , Xe As Integer , Ye As Integer) ';Längen für x und y ausrechnen Xlen = Xe - Xs Ylen = Ye - Ys ';Schrittrichtung für x und Y festlegen If Xlen >= 0 Then Xa = 1 Else Xa = 255 If Ylen >= 0 Then Ya = 1 Else Ya = 255 ';wenn xlänge grösser ist, dann laufen wir an der X-Achse entlang '; ansonsten an der Y-Achse If Xlen < 0 Then Xlen = Xlen * -1 If Ylen < 0 Then Ylen = Ylen * -1 If Xlen < Ylen Then Goto Walky Walkx: Z = 0 'licht einschalten Temp = Xlen Do Porta = Low(xs) Portc = Low(ys) Waitus 1 Xs = Xs + Xa ':immer einen Schritt in x-Richtung weiter Temp = Temp - Ylen ';Schritt in Y-Richtung nötig ? If Temp <= 0 Then ';wenn <=0 dann ja Temp = Temp + Xlen '; Ys = Ys + Ya ';Schritt in Y-Richtung End If Loop Until Low(xs) = Low(xe) ';Wiederholen bis Ende der Linie Goto Endofsub Walky: Z = 0 Temp = Ylen Do Porta = Low(xs) Portc = Low(ys) Waitus 1 Ys = Ys + Ya Temp = Temp - xlen If Temp < 0 Then Temp = Temp + Ylen Xs = Xs + Xa End If Loop Until Low(ys) = Low(ye) Endofsub: Z = 1 'und wieder aus End Sub
Hallo, habe den code gleich mal probiert.
hatte noch ein anderes problem, das mir vorher nicht aufgefallen ist (siehe bild) Portc ist bestimmt irgendwie durch was anderes belegt, habe portd genommen, jetzt ist die y-linie okay...
Was den code angeht scheint er nicht zu laufen...
Er zeichnet nur eine linie von 0/0 bis 0/30 (ca 1cm hoch)
Hallo,
ich hab mir jetzt mal selbst was zum Testen zusammen gestrickt.
Und bei mir läuft die Line-Sub.
Jedenfalls auf meinem ATmega32.
Ich musste das Programm etwas vereinfachen, damit
meine Testversion-Bascom mit dem Speicher auskommt.
Aber das Prinzip der Line-Routine ist geblieben.
Auf dem Prinzip kann man aufsetzen...
Die Line-Draw Routine werde ich in Assembler schreiben,
damit es richtig schnell wird.
@Sebastian: Testest du mal ?
Gruß Jan
Code:$regfile = "m32def.dat" $crystal = 16000000 '#########Variablen Line Funktion Dim Xs As Integer Dim Xe As Integer Dim Ys As Integer Dim Ye As Integer Dim Xlen As Integer Dim Ylen As Integer Dim Xa As Integer Dim Ya As Integer Dim Temp As Integer Dim N As Byte '################################# Declare Sub Drawline() Config Porta = Output Config Portc = Output 'Z Alias Portf.1 'Z = 1 ' dunkel Do Restore Daten: For N = 1 To 14 Read Xs Read Ys Read Xe Read Ye Call Drawline() Next Loop End Sub Drawline() ';Längen für x und y ausrechnen Xlen = Xe - Xs Ylen = Ye - Ys ';Schrittrichtung für x und Y festlegen If Xlen >= 0 Then Xa = 1 Else Xa = 255 If Ylen >= 0 Then Ya = 1 Else Ya = 255 ';wenn xlänge grösser ist, dann laufen wir an der X-Achse entlang '; ansonsten an der Y-Achse If Xlen < 0 Then Xlen = Xlen * -1 If Ylen < 0 Then Ylen = Ylen * -1 If Xlen < Ylen Then Goto Walky Walkx: ' Z = 0 'licht einschalten Temp = Xlen Shift Temp , Right , 1 Do Porta = Low(xs) Portc = Low(ys) Waitus 1 Xs = Xs + Xa ':immer einen Schritt in x-Richtung weiter Temp = Temp - Ylen ';Schritt in Y-Richtung nötig ? If Temp <= 0 Then ';wenn <=0 dann ja Temp = Temp + Xlen '; Ys = Ys + Ya ';Schritt in Y-Richtung End If Loop Until Low(xs) = Low(xe) ';Wiederholen bis Ende der Linie Goto Endofsub Walky: ' Z = 0 Temp = Ylen Shift Temp , Right , 1 Do Porta = Low(xs) Portc = Low(ys) Waitus 1 Ys = Ys + Ya Temp = Temp - Xlen If Temp < 0 Then Temp = Temp + Ylen Xs = Xs + Xa End If Loop Until Low(ys) = Low(ye) Endofsub: 'Z = 1 'und wieder aus End Sub Daten: Data 0% , 0% , 200% , 0% Data 200% , 0% , 200% , 200% Data 200% , 200% , 0% , 200% Data 0% , 200% , 0% , 0% Data 20% , 20% , 180% , 80% Data 180% , 80% , 80% , 180% Data 80% , 180% , 20% , 20% Data 100% , 120% , 80% , 120% Data 80% , 120% , 80% , 100% Data 80% , 100% , 90% , 100% Data 90% , 100% , 100% , 90% Data 100% , 90% , 100% , 80% Data 100% , 80% , 90% , 70% Data 90% , 70% , 80% , 70%
Na prima, grins. Also ich werds morgen früh gleich mal testen. Bin schon ganz aufgeregt...
@jan: du machst keine pausen (wait) mehr? hatte angst das man gar nix mehr sieht... assembler ist natürlich schon geil, aber der µCOM assembler etwas undurchsichtig. (hatte mal nen grundkurs mit TASM vor jahren) Hast du 10/20k gewählt oder kleiner?
Lesezeichen