sources:


website:
more info here


screenshot:
studies/grafik/Computergrafik-Code4/Aufgabe9/cgellipse.cpp
download file

  1 // Computergraphik I
  2 // Prof. Dr. Juergen Doellner
  3 // Sommersemester 2001
  4 //
  5 // Rahmenprogramm fuer Aufgabenzettel 4
  6
  7 // Stephan Brumme, 702544
  8 // last changes: May 19, 2001
  9
 10 #include "cgellipse.h"
 11
 12
 13 CGEllipse::CGEllipse(int width, int height) : raster_(width,height) {
 14     // Objektvariablen initialisieren
 15     First_ = true;
 16 }
 17
 18 void CGEllipse::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 CGEllipse::onDraw() {
 29     // Colorbuffer loeschen
 30     glClear(GL_COLOR_BUFFER_BIT);
 31
 32     // Zeichenen der Raster-Klasse
 33     raster_.draw();
 34        
 35     // Backbuffer anzeigen
 36     swapBuffers();
 37 }
 38
 39 void CGEllipse::onSize(unsigned int newWidth, unsigned int newHeight) {
 40     // neue Fenstergröße speichern
 41     winWidth_ = newWidth;
 42     winHeight_ = newHeight;
 43     glViewport(0, 0, newWidth - 1, newHeight - 1);
 44 }
 45
 46 void CGEllipse::onButton(MouseButton button, MouseButtonEvent event, int x, int y) {
 47     // Sichern der x und y Werte
 48     // Anfang und Ende unterscheiden durch MouseButtonEvent:
 49     // MouseButtonDown = Start
 50     // MouseButtonUp = End
 51
 52     // Mausposition in Rasterkoordinaten umrechnen
 53     x = (int)(0.5 + x / ((float)winWidth_ /(raster_.width()-1)));
 54     y = (int)(0.5 + y / ((float)winHeight_/(raster_.height()-1)));
 55
 56     // Linienanfang
 57     if (event == MouseButtonDown)
 58     {
 59         xBegin_ = x;
 60         yBegin_ = y;
 61     }
 62    
 63     // Linienende
 64     if (event == MouseButtonUp)
 65     {
 66         xEnd_ = x;
 67         yEnd_ = y;
 68         // Endpunkt steht fest, Linie darf gezeichnet werden
 69         First_ = false;
 70     }
 71
 72     // Raster löschen
 73     raster_.clear();
 74     // Linie im Raster zeichnen
 75     if (!First_)
 76         drawEllipse(xBegin_, yBegin_, xEnd_, yEnd_);
 77
 78     // Raster auf dem Bildschirm darstellen
 79     onDraw();
 80 }
 81
 82 void CGEllipse::onMove(MouseButton button, int x, int y) {
 83     // Endpunkt ermitteln
 84     onButton(button, MouseButtonUp, x, y);
 85 }
 86
 87 void CGEllipse::drawEllipsePoints(int midx, int midy, int x, int y)
 88 {
 89     // zeichne in allen 4 Quadranten, beachte Verschiebung aus Ursprung heraus
 90     raster_.setPixel(midx+x, midy+y);
 91     raster_.setPixel(midx+x, midy-y);
 92     raster_.setPixel(midx-x, midy+y);
 93     raster_.setPixel(midx-x, midy-y);
 94 }
 95
 96 void CGEllipse::drawEllipse(int x1, int y1, int x2, int y2) {
 97     // Ellipsen Algorithmus
 98     // Zeichnen mit der Raster-Klasse
 99
100     // ändere ggf. Eckpunkte, sodass untere linke Ecke per x1/y1
101     // und obere rechte per x2/y2 definiert wird
102     if (x2 < x1)
103     {
104         int temp;
105
106         temp = x2;
107         x2 = x1;
108         x1 = temp;
109     }
110     if (y2 < y1)
111     {
112         int temp;
113
114         temp = y2;
115         y2 = y1;
116         y1 = temp;
117     }
118
119     // Ellipsenparameter
120     int A = (y2-y1) / 2;
121     int B = (x2-x1) / 2;
122     int A2= A*A;
123     int B2= B*B;
124
125     // verweigere zu kleine Ellipsen
126     if (A == 0 || B == 0)
127         return;
128    
129     // Ellipsenmittelpunkt
130     int midX = x1+B;
131     int midY = y1+A;
132
133     // oben mittig beginnen
134     int x = 0;
135     int y = A;
136
137     // "Enden" der Ellipsen zeichnen
138     drawEllipsePoints(midX, midY, 0, A);
139
140     // Entscheidungsvariable für E/SE
141     int d1  = A2-A*B2+B2/4;
142
143     // Inkremente 1. und 2.Ordnung für x und y
144     int dX  = A2*3;
145     int ddX = A2*2;
146     int dY  = B2*(-2*A+2);
147     int ddY = 2*B2;
148
149     // solange in Region 1
150     while (dX < -dY || d1 < 0)
151     {
152
153         // nach Süden ?
154         if (d1 > 0)
155         {
156             d1 += dY;
157             dY += ddY;
158             y--;
159         }
160
161         // immer nach Osten
162         d1 += dX;
163         dX += ddX;
164         x++;
165
166         // alle 4 Quadranten zeichnen
167         drawEllipsePoints(midX, midY, x, y);
168     }
169
170
171     // Entscheidungsvariable für SE/S
172     int d2 = A2*x*x+A2*x + B2*(y-1)*(y-1) - A2*B2;
173
174     // Inkremente 1.Ordnung für x und y
175     dX     = A2*(2*x+2);
176     dY     = B2*(-2*y+3);
177     // Inkremente 2.Ordnung können unverändert aus Region 1 übernommen werden
178
179     // bis x-Achse errreicht
180     while (y > 0)
181     {
182         // nach Osten ?
183         if (d2 < 0)
184         {
185             d2 += dX;
186             dX += ddX;
187             x++;
188         }
189
190         // immer nach Süden
191         d2 += dY;
192         dY += ddY;
193         y--;
194
195         // alle 4 Quadranten zeichnen
196         drawEllipsePoints(midX, midY, x, y);
197     }
198 }
199
200 int main(int argc, char* argv[]) {
201     CGEllipse ellipse(81, 81);
202     ellipse.start(argc, argv, "CGEllipse, Stephan Brumme, 702544");
203     return(0);
204 }
205
206