sources:
cgapplication.cpp (3.6k)
cgapplication.h (4.1k)
cgmidpoint.cpp (4.0k)
cgmidpoint.h (1024 bytes)
cgraster.cpp (2.2k)
cgraster.h (713 bytes)


website:
more info here


screenshot:
studies/grafik/Computergrafik-Code3/cgmidpoint.cpp
download file

  1 // Computergraphik I
  2 // Prof. Dr. Juergen Doellner
  3 // Sommersemester 2001
  4 //
  5 // Rahmenprogramm fuer Aufgabenzettel 3
  6
  7 // Stephan Brumme, 702544
  8 // last changes: May 17, 2001
  9
 10 #include "cgmidpoint.h"
 11
 12
 13 CGMidpoint::CGMidpoint(int width, int height) : raster_(width,height) {
 14     // Objektvariablen initialisieren
 15     First_ = true;
 16 }
 17
 18 void CGMidpoint::onInit() {
 19     // Hintergrundfarbe weiss
 20     glClearColor(1, 0.9, 0.8, 1);
 21
 22     // ohne perspektivische Verzerrung, da nur 2D
 23     glMatrixMode(GL_PROJECTION);
 24     glLoadIdentity();
 25     gluOrtho2D(0, raster_.width()-1, 0, raster_.height()-1);
 26 }
 27
 28 void CGMidpoint::onDraw() {
 29     // Colorbuffer loeschen
 30     glClear(GL_COLOR_BUFFER_BIT);
 31
 32     // Zeichenen der Raster-Klasse
 33     raster_.draw();
 34        
 35     // Zeichenen einer roten Kontroll-Linie
 36     // mit OpenGL
 37
 38     // erst durchführen, wenn ein Endpunkt feststeht
 39     if (!First_)
 40     {
 41         // Umgebung sichern
 42         glPushAttrib(GL_CURRENT_BIT);
 43         // rote Linie
 44         glColor3f(1.0, 0.0, 0.0);
 45
 46         // und Hilfslinie zeichnen
 47         glBegin(GL_LINES);
 48         glVertex2f(xBegin_, yBegin_);
 49         glVertex2f(xEnd_  , yEnd_  );
 50         glEnd();
 51         // Umgebung wiederherstellen
 52         glPopAttrib();
 53     }
 54    
 55     // Backbuffer anzeigen
 56     swapBuffers();
 57 }
 58
 59 void CGMidpoint::onSize(unsigned int newWidth, unsigned int newHeight) {
 60     // neue Fenstergröße speichern
 61     winWidth_ = newWidth;
 62     winHeight_ = newHeight;
 63     glViewport(0, 0, newWidth - 1, newHeight - 1);
 64 }
 65
 66 void CGMidpoint::onButton(MouseButton button, MouseButtonEvent event, int x, int y) {
 67     // Sichern der x und y Werte
 68     // Anfang und Ende unterscheiden durch MousButtonEvent:
 69     // MouseButtonDown = Start
 70     // MouseButtonUp = End
 71
 72     // Mausposition in Rasterkoordinaten umrechnen
 73     x = (int)(0.5 + x / ((float)winWidth_ /(raster_.width()-1)));
 74     y = (int)(0.5 + y / ((float)winHeight_/(raster_.height()-1)));
 75
 76     // Linienanfang
 77     if (event == MouseButtonDown)
 78     {
 79         xBegin_ = x;
 80         yBegin_ = y;
 81     }
 82    
 83     // Linienende
 84     if (event == MouseButtonUp)
 85     {
 86         xEnd_ = x;
 87         yEnd_ = y;
 88         // Endpunkt steht fest, Linie darf gezeichnet werden
 89         First_ = false;
 90     }
 91
 92     // Raster löschen
 93     raster_.clear();
 94     // Linie im Raster zeichnen
 95     if (!First_)
 96         drawLine(xBegin_, yBegin_, xEnd_, yEnd_);
 97
 98     // Raster auf dem Bildschirm darstellen
 99     onDraw();
100 }
101
102 void CGMidpoint::onMove(MouseButton button, int x, int y) {
103     // Endpunkt ermitteln
104     onButton(button, MouseButtonUp, x, y);
105 }
106
107 void CGMidpoint::drawLine(int x1, int y1, int x2, int y2) {
108     // Bresenham Algorithmus
109     // Zeichnen mit der Raster-Klasse
110
111     // zeichne immer von links nach rechts, vertausche ggf. Eckpunkte
112     if (x2 < x1)
113     {
114         int temp;
115
116         temp = x2;
117         x2 = x1;
118         x1 = temp;
119
120         temp = y2;
121         y2 = y1;
122         y1 = temp;
123     }
124
125     // dx ist immer nicht-negativ (aufgrund des vorhergehendes Tausches von x1,x2)
126     int dx = x2 - x1;
127     // dy kann auch negativ sein ...
128     int dy = y2 - y1;
129
130     // berechne Steigung pro Iteration entlang der y-Achse
131     int ystep = 1;
132     if (dy < 0)
133     {
134         ystep = -1;
135         // ab jetzt ist dy immer nicht-negativ
136         dy = -dy;
137     }
138
139     // Steigung <= 1 ?
140     if (dy <= dx)
141     {
142         // Standardalgorithmus aus Vorlesung, lediglich y++ durch y += ystep ersetzt
143         int d  = 2*dy - dx;
144         int dE = 2*dy;
145         int dNE= 2*(dy-dx);
146         int x  = x1;
147         int y  = y1;
148
149         raster_.setPixel(x,y);
150
151         while(x != x2)
152         {
153             if (d <= 0)
154                 d += dE;
155             else             {
156                 d += dNE;
157                 y += ystep;
158             }
159             x++;
160
161             raster_.setPixel(x,y);
162         }
163     }
164     else     {
165         // alle x durch y ersetzt (und umgekehrt, auch dx und dy !),
166         // lediglich setPixel blieb jeweils unverändert
167         int d  = 2*dx - dy;
168         int dNE= 2*dx;
169         int dN = 2*(dx-dy);
170         int x  = x1;
171         int y  = y1;
172
173         raster_.setPixel(x,y);
174
175         while(y != y2)
176         {
177             if (d <= 0)
178                 d += dNE;
179             else             {
180                 d += dN;
181                 x++;
182             }
183             y += ystep;
184
185             raster_.setPixel(x,y);
186         }
187     }
188 }
189
190 int main(int argc, char* argv[]) {
191     CGMidpoint bresenham(30, 30);
192     bresenham.start(argc, argv, "CGMidpoint, Stephan Brumme, 702544");
193     return(0);
194 }
195
196