#1 10. Februar 2009 Linie zeichnen Hallo liebe Mitglieder! ich bin ein armer informatik lk schüler und bin leider nicht soo der hellste, was grundlegende dinge angeht mein lehrer meinte ich sollte doch mal was zu dem thema linie und dann fortführend kreis zeichenen vorbereiten! also was ein pc da so genau macht was berechnet wird und was zusatzläich gemacht wird mit antalising und son kram! er meinte das thema wäre sehr weitumgreifend und ich könnte dazu viel herausarbeiten, doch ich find jez ncih so viel und bin ein wenig verzweifelt.... habt ihr vlt ein paar gute quellen wo ich sowas rausarbeiten kann, was auch verständlich ist und könnt evtl ein wenig erklären! er meinte ich sollte da schon einiges zu machen =/ und evtl sogar noch ein programier beispiel zum abschluss bringen....wir arbeiten mit delphiß aber jez nicht so genau wie ich das da machen muss, aber erstmal müsse ich ja auch verstehen wie das ganze funktionert! wäre sehr dankbar für hilfe, mfg! + Multi-Zitat Zitieren
#2 10. Februar 2009 AW: Linie/Kreis zeichnen hier mal was so grundsätzlich möglich ist: http://www.joerg-rudolf.lehrer.belwue.de/gkinfo/delphi/zeichnen.htm zum rest ... schnapp dir dazu am besten n gutes buch (habt doch sicher eines empfohlen bekommen? ). da wird im normalfall auch erklärt was so abläuft im hintergrund wenn du zeichnest. hier wird erklärt wie der zusammenhang mit rechteck und api etc. is: Re: Informatik Grundlagen, z.B. zeichnen eines Rechtecks ev. auch hilfreich: http://209.85.129.132/search?q=cache:5Wcs7rMZVnIJ:www.friedrich.fr.schule-bw.de/delphi/delphi2/delphi2.doc+zeichnen+delphi+ablauf&hl=de&ct=clnk&cd=7&gl=at&client=firefox-a + Multi-Zitat Zitieren
#3 10. Februar 2009 AW: Linie/Kreis zeichnen danke schonmal, aber das ist glaub ich schon zu konkret auf delphi, das brauch ich erst später... ich denke allgemeiner gehalten, was der computer rechnet bei einer linie etc =/ + Multi-Zitat Zitieren
#4 10. Februar 2009 AW: Linie/Kreis zeichnen steht im zweiten link hier ev. was dir auch noch helfen könnte wie ein bild überhaupt aufgebaut wird. mit dem wissen sollte eig. klar sein was passiert wenn du ne linie zeichnest! http://www.medien.ifi.lmu.de/lehre/ss03/mt/Grafikkarten.pdf + Multi-Zitat Zitieren
#5 15. Februar 2009 AW: Linie/Kreis zeichnen ich schätze ma wo dein lehrer eigentliuch drauf raus will ist folgendes: eine linie am rechner zu zeichnen ist nicht ganz trivial. schließlich sind alles pixel. solange man nur 0, 45, 90, etc grad zeichnet, geht das, aber sobald es zwischenwinkel sind, muss man einen algorithmus finden, der berechnet welcher pixel jetzt gefüllt werden soll oder nicht. Bresenham-Algorithmus – Wikipedia gibt auch einen bresenham-kreis-algorithmus. + Multi-Zitat Zitieren
#6 16. Februar 2009 AW: Linie/Kreis zeichnen jo...hat er mir jez auch gesagt^^ aber das kreis zeichnen lassen wir jez iwie doch raus.... muss bresenham in 3 schritten erklären anhand folgendem programm.... kann mir vlt jemand helfen?! Code: UNIT mT2DGrafik; interface //-------------------- ggf Uses-Liste anpassen ! -------------------- uses mT2DPunkt, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, math, StdCtrls; type T2DGrafik = CLASS // weitere Attribute private zRichtung : Integer; zStartpunkt : T2DPunkt; //Objektbeziehungen: // kenntT2DPunkt : T2DPunkt; // weitere Methoden public constructor create(pStartPunkt:T2Dpunkt); procedure BresenhamLinie(pZiel:T2DPunkt); procedure bresenham_1(pZiel : T2DPunkt); procedure bresenham_2(pZiel : T2DPunkt); procedure bresenham_3(pZiel : T2DPunkt); procedure destroy; procedure linieeinfach(pZiel:T2DPunkt); procedure linieverbesert(pZiel:T2DPunkt); procedure Richtungslinie(plaenge:Integer); procedure SetzeZRichtung(pZRichtung:Integer); procedure SetzeZStartpunkt(pZStartpunkt:T2DPunkt); function GibZRichtung : Integer; function GibZStartpunkt : T2DPunkt; end; implementation //+--------------------------------------------------------------------- //| T2DGrafik: Methodendefinition //+--------------------------------------------------------------------- //-------- create (public) --------------------------------------------- constructor T2DGrafik.create(pStartPunkt:T2Dpunkt); begin zStartPunkt:=pStartPunkt; zRichtung:=0; end; //-------- bresenham_1 (public) ---------------------------------------- // zeichnet linien mit Steigung zwischen -1 und 1, da y maximal um so viel erhöht wird, wie x //-------- BresenhamLinie (public) ------------------------------------- //Problem: Nur ganzzahlige Schritte möglich in Pixelgrafik. // Idee: Berechne den nächsten y-Wert aus dem vorherigen und Speichere den Fehler //Wenn dieser >0.5 y-Wert hochzählen //Varianten 1-3 bauen Schrittweise aufeinander auf. //Varianten 1-3 arbeiten nur für Linien im ersten Oktanden (0 < m <= 1) procedure T2DGrafik.bresenham_1(pZiel : T2DPunkt); Var lPunkt : T2DPunkt; deltaX, deltaY : Integer; m, Fehler : double; // m=Steigung begin deltaX:= pZiel.GibZx - zStartPunkt.GibZx; deltaY:= pZiel.GibZY - zStartPunkt.GibZY; Fehler:=0.0; m:= deltaY/deltaX; end; //-------- bresenham_2 (public) ---------------------------------------- // Erste Verbesserung: Gleitkommazahlen vermeiden // Idee: dy/dx > 0.5 <=> 2dy > dx // Weiterhin nur erster Oktant. procedure T2DGrafik.bresenham_2(pZiel : T2DPunkt); Var lPunkt : T2DPunkt; deltaX, deltaY, Fehler : Integer; begin end; //-------- bresenham_3 (public) ---------------------------------------- //Vergleich mit 0 statt mit dx, Idee: dy/dx > 0.5 <=> 2dy - dx > 0 //Außerdem: Abkürzungen: delta = 2 dy; schwelle = -2dx //Weiterhin: Nur erster Oktant. procedure T2DGrafik.bresenham_3(pZiel : T2DPunkt); Var lPunkt : T2DPunkt; deltaX, deltaY, Fehler, delta, schwelle : Integer; begin deltaX:= pZiel.GibZx - zStartPunkt.GibZx; deltaY:= pZiel.GibZY - zStartPunkt.GibZY; Fehler:=-deltaX; //Achtung!!! delta:=2*deltaY; schwelle:=-2*deltaX ; end; //-------- BresenhamLinie (public) ------------------------- //Arbeitet mit dem Prinzip von Breseham_3, aber nicht nur //im ersten Quadranten. procedure T2DGrafik.BresenhamLinie(pZiel:T2DPunkt); Var lPunkt : T2DPunkt; deltaX, deltaY, Fehler, delta, schwelle, inc_x, inc_y : Integer; begin deltaX:= pZiel.GibZx - zStartPunkt.GibZx; deltaY:= pZiel.GibZY - zStartPunkt.GibZY; end; //-------- destroy (public) -------------------------------------------- procedure T2DGrafik.destroy; begin end; //-------- linieeinfach (public) y= m*x + b------------------------------- // x Wert des Punktes wird um 1 erhöht, y Wert wird berechnet //-------- linieeinfach (public) --------------------------------------- procedure T2DGrafik.linieeinfach(pZiel:T2DPunkt); Var lPunkt : T2DPunkt; m,b: Real; begin if pZiel.GibZx - zStartPunkt.GibZx <> 0 then Begin m:= (pZiel.GibZY - zstartpunkt.GibZX)/(pZiel.GibZx - zStartPunkt.GibZx); b:= (pZiel.GibZX * zStartPunkt.GibZY - pZiel.GibZY * zStartPunkt.GibZX)/ (pZiel.GibZx - zStartPunkt.GibZx); lPunkt:=T2DPunkt.create(zStartPunkt.GibZX,zStartPunkt.GibZY); While (lPunkt.GibZX < pZiel.GibZX) do Begin lPunkt.zeichneDich; lPunkt.SetzeZY( Trunc((m*lPunkt.GibZX + b + 0.5))); lPunkt.setzeZX(lPunkt.GibZX + 1) End; end else showmessage('Geht nicht'); lPunkt.destroy; end; //-------- linieverbesert (public) ------------------------------------- //wie in LinieEinfach wird nur noch für -1 < m < 1 vorgegangen, sonst wird y erhöht und x berchnet. //Außerdem wird die Richtung beachtet. //-------- linieverbesert (public) ------------------------------------- procedure T2DGrafik.linieverbesert(pZiel:T2DPunkt); Var lPunkt : T2DPunkt; m,b: Real; deltaX, deltaY : Integer; begin deltaX:= pZiel.GibZx - zStartPunkt.GibZx; deltaY:= pZiel.GibZY - zstartpunkt.GibZX; if abs(deltaX) >= abs(deltaY) then Begin m:= deltaY/deltaX; b:= (pZiel.GibZX * zStartPunkt.GibZY - pZiel.GibZY * zStartPunkt.GibZX)/ deltaX; lPunkt:=T2DPunkt.create(zStartPunkt.GibZX,zStartPunkt.GibZY); While (lPunkt.GibZX < pZiel.GibZX) do Begin lPunkt.zeichneDich; lPunkt.SetzeZY( Trunc((m*lPunkt.GibZX + b + 0.5))); lPunkt.setzeZX(lPunkt.GibZX + 1) End; While (lPunkt.GibZX > pZiel.GibZX) do Begin lPunkt.zeichneDich; lPunkt.SetzeZY( Trunc((m*lPunkt.GibZX + b + 0.5))); lPunkt.setzeZX(lPunkt.GibZX - 1) End; end else begin m:= deltaX/deltaY; b:= (zStartPunkt.GibZX * pZiel.GibZY - zStartPunkt.GibZY * pZiel.GibZX)/ deltaY; lPunkt:=T2DPunkt.create(zStartPunkt.GibZX,zStartPunkt.GibZY); While (lPunkt.GibZY < pZiel.GibZY) do Begin lPunkt.zeichneDich; lPunkt.SetzeZX( Trunc((m*lPunkt.GibZY + b + 0.5))); lPunkt.setzeZY(lPunkt.GibZY + 1) End; While (lPunkt.GibZY > pZiel.GibZY) do Begin lPunkt.zeichneDich; lPunkt.SetzeZX( Trunc((m*lPunkt.GibZY + b + 0.5))); lPunkt.setzeZY(lPunkt.GibZY - 1) End; end; lPunkt.destroy; end; //-------- Richtungslinie (public) ------------------------------------- procedure T2DGrafik.Richtungslinie(plaenge:Integer); Var lPunkt: T2DPunkt; l_x, l_y : Integer; begin l_x:=round(plaenge*cos(zRichtung*PI/180)); l_y:=round(plaenge*sin(zRichtung*PI/180)); l_x:=l_x+zStartPunkt.GibZX; l_y:=l_y+zStartPunkt.GibZY; //showmessage(IntToStr(l_x)); lPunkt:=T2DPunkt.create(l_x,l_y); self.BresenhamLinie(lPunkt); lPunkt.destroy; end; //-------- SetzeZRichtung (public) ------------------------------------- procedure T2DGrafik.SetzeZRichtung(pZRichtung:Integer); begin zRichtung := pZRichtung end; //-------- SetzeZStartpunkt (public) ----------------------------------- procedure T2DGrafik.SetzeZStartpunkt(pZStartpunkt:T2DPunkt); begin zStartpunkt := pZStartpunkt end; //-------- GibZRichtung (public) --------------------------------------- function T2DGrafik.GibZRichtung : Integer; begin result := zRichtung end; //-------- GibZStartpunkt (public) ------------------------------------- function T2DGrafik.GibZStartpunkt : T2DPunkt; begin result := zStartpunkt end; end. die klasse wird genutzt Code: UNIT mT2DPunkt; interface //-------------------- ggf Uses-Liste anpassen ! -------------------- uses mSuM; type T2DPunkt = CLASS // weitere Attribute private zX : Integer; zY : Integer; hatStift : Stift; //Objektbeziehungen: // kenntT2DGrafik () of T2DGrafik; // weitere Methoden public constructor create(pX,pY:Integer); procedure SetzeZX(pZX:Integer); procedure SetzeZY(pZY:Integer); procedure zeichneDich; function GibZX : Integer; function GibZY : Integer; destructor destroy; end; implementation //+--------------------------------------------------------------------- //| T2DPunkt: Methodendefinition //+--------------------------------------------------------------------- //-------- create (public) --------------------------------------------- constructor T2DPunkt.create(pX,pY:Integer); begin zX:=pX; zY:=pY; hatStift:=Stift.init; end; //-------- SetzeZX (public) -------------------------------------------- procedure T2DPunkt.SetzeZX(pZX:Integer); begin zX := pZX end; //-------- SetzeZY (public) -------------------------------------------- procedure T2DPunkt.SetzeZY(pZY:Integer); begin zY := pZY end; //-------- zeichneDich (public) ---------------------------------------- procedure T2DPunkt.zeichneDich; begin hatStift.bewegeBis(zX,zY); hatstift.zeichneKreis(1); hatStift.hoch; end; //-------- GibZX (public) ---------------------------------------------- function T2DPunkt.GibZX : Integer; begin result := zX end; //-------- GibZY (public) ---------------------------------------------- function T2DPunkt.GibZY : Integer; begin result := zY end; //-------- destroy (public) -------------------------------------------- destructor T2DPunkt.destroy; begin hatStift.gibFrei; end; end. Also setzten wir jez mal bei bresenham_1 an... als erstes hol ich mir den startpunkt: Code: lPunkt:=T2DPunkt.create(zStartPunkt.GibZX, zStartPunkt.GibZY); und dann muss ich halt die ganzen x werte durchgehen, bis er am zielpunkt angekommen ist... Code: While (lPunkt.GibZX < pZiel.GibZX) do begin lPunkt.zeichnedich; lPunkt.setzeZX(lPunkt.GibZX + 1); aber wozu brauch ich die variable fehler und wie berechne ich dann damit den y wert ?! + Multi-Zitat Zitieren