void initialize();
+ void applyColor();
+
void safeLock(QMutex &mutex);
void safeUnlock(QMutex &mutex);
void DrawingWindow::setColor(float red, float green, float blue)
{
d->fgColor.setRgbF(red, green, blue);
- QPen pen(d->painter->pen());
- pen.setColor(d->fgColor);
- d->painter->setPen(pen);
+ d->applyColor();
+}
+
+void DrawingWindow::setColor(const char *name)
+{
+ d->fgColor.setNamedColor(name);
+ d->applyColor();
}
void DrawingWindow::setBgColor(float red, float green, float blue)
d->bgColor.setRgbF(red, green, blue);
}
+void DrawingWindow::setBgColor(const char *name)
+{
+ d->bgColor.setNamedColor(name);
+}
+
void DrawingWindow::clearGraph()
{
d->safeLock(d->imageMutex);
void DrawingWindow::drawRect(int x1, int y1, int x2, int y2)
{
QRect r;
- r.setCoords(x1, y1, x2, y2);
+ r.setCoords(x1, y1, x2 - 1, y2 - 1);
r = r.normalized();
d->safeLock(d->imageMutex);
d->painter->drawRect(r);
d->safeUnlock(d->imageMutex);
}
+void DrawingWindow::fillRect(int x1, int y1, int x2, int y2)
+{
+ d->painter->setBrush(d->fgColor);
+ drawRect(x1, y1, x2, y2);
+ d->painter->setBrush(Qt::NoBrush);
+}
+
+void DrawingWindow::drawCircle(int x, int y, int r)
+{
+ QRect rect;
+ rect.setCoords(x - r, y - r, x + r - 1, y + r - 1);
+ d->safeLock(d->imageMutex);
+ d->painter->drawEllipse(rect);
+ rect.adjust(0, 0, 1, 1);
+ d->dirty(rect);
+ d->safeUnlock(d->imageMutex);
+}
+
+void DrawingWindow::fillCircle(int x, int y, int r)
+{
+ d->painter->setBrush(d->fgColor);
+ drawCircle(x, y, r);
+ d->painter->setBrush(Qt::NoBrush);
+}
+
bool DrawingWindow::sync(unsigned long time)
{
bool synced;
q->setAttribute(Qt::WA_OpaquePaintEvent);
q->setFocus();
- q->setColor(0.0, 0.0, 0.0); // black
- q->setBgColor(1.0, 1.0, 1.0); // white
+ q->setColor("black");
+ q->setBgColor("white");
q->clearGraph();
dirtyFlag = false;
delete image;
}
+inline
+void DrawingWindowPrivate::applyColor()
+{
+ QPen pen(painter->pen());
+ pen.setColor(fgColor);
+ painter->setPen(pen);
+}
+
inline
void DrawingWindowPrivate::safeLock(QMutex &mutex)
{
const int width;
const int height;
+ // http://www.w3.org/TR/SVG/types.html#ColorKeywords
void setColor(float red, float green, float blue);
+ void setColor(const char *name);
void setBgColor(float red, float green, float blue);
+ void setBgColor(const char *name);
void clearGraph();
void drawPoint(int x, int y);
void drawLine(int x1, int y1, int x2, int y2);
void drawRect(int x1, int y1, int x2, int y2);
+ void fillRect(int x1, int y1, int x2, int y2);
+ void drawCircle(int x, int y, int r);
+ void fillCircle(int x, int y, int r);
bool sync(unsigned long time = ULONG_MAX);
--- /dev/null
+#include <QApplication>
+#include <DrawingWindow.h>
+#include <cmath>
+#include <iostream>
+#include <ctime>
+#include <cstdlib>
+
+/* Note : les coordonnées réelles vont de -100 à +100 en abscisse, et
+ * de -10 à +140 en ordonnée
+ */
+
+const float rXMin = -100.0;
+const float rXMax = 100.0;
+const float rYMin = -10.0;
+const float rYMax = 140.0;
+
+const float hauteurMin = 10;
+const float hauteurMax = 130;
+const float largeurMin = 40;
+const float largeurMax = 150;
+
+const float positionChateau1 = -85.0;
+const float positionChateau2 = 85.0;
+
+/* Retourne un nombre pseudo-aléatoire compris entre 0 et le paramètre
+ * 'max' (exclus)
+ */
+float frand(float min, float max)
+{
+ static bool first = true;
+ if (first) {
+ srand(time(NULL));
+ first = false;
+ }
+ return min + (max - min)* (rand() / (RAND_MAX + 1.0));
+}
+
+// conversion coordonnées réelles -> coordonnées fenêtre
+int rtowX(const DrawingWindow& w, float rx)
+{
+ return (int )roundf(w.width * (rx - rXMin) / (rXMax - rXMin + 1.0));
+}
+
+int rtowY(const DrawingWindow& w, float ry)
+{
+ return (int )roundf(w.height * (rYMax - ry) / (rYMax - rYMin + 1.0));
+}
+
+// conversion coordonnées réelles -> coordonnées fenêtre
+float wtorX(const DrawingWindow& w, int wx)
+{
+ return (rXMax - rXMin + 1.0) * wx / w.width + rXMin;
+}
+
+float wtorY(const DrawingWindow& w, int wy)
+{
+ return -(rYMax - rYMin + 1.0) * wy / w.height - rYMax;
+}
+
+void dessineTerrain(DrawingWindow& w, float largeur, float hauteur)
+{
+ float l = largeur / 2.0;
+ float h = hauteur;
+ int y0 = rtowY(w, 0) + 1;
+ int xmin = rtowX(w, -l) - 1;
+ int xmax = rtowX(w, l) + 1;
+ w.setColor("forestgreen");
+ for (int x = xmin; x <= xmax; x++) {
+ float rx = wtorX(w, x) / l;
+ float ry = h * (1.0 - rx * rx);
+ int y = rtowY(w, ry);
+ if (y <= y0)
+ w.drawLine(x, y0, x, y);
+ }
+ w.setColor("maroon");
+ w.fillRect(0, y0 + 1, w.width - 1, w.height - 1);
+}
+
+void dessineChateau(DrawingWindow& w, float position)
+{
+ w.setColor("black");
+ w.setColor("darkslategray");
+ int y1 = rtowY(w, 0);
+ int h0 = rtowY(w, 3);
+ int h1 = rtowY(w, 4);
+ for (int i = 0; i < 7; i++) {
+ int h = i % 2 ? h0 : h1;
+ int x1 = rtowX(w, position + i - 3.5);
+ int x2 = rtowX(w, position + i - 2.5) - 1;
+ w.fillRect(x1, y1, x2, h);
+ }
+ w.setColor("dimgray");
+ h0 = rtowY(w, 6);
+ h1 = rtowY(w, 7);
+ for (int i = 0; i < 5; i++) {
+ int h = i % 2 ? h0 : h1;
+ int x1 = rtowX(w, position + i - 8.5);
+ int x2 = rtowX(w, position + i - 7.5) - 1;
+ w.fillRect(x1, y1, x2, h);
+ x1 = rtowX(w, position + i + 3.5);
+ x2 = rtowX(w, position + i + 4.5) - 1;
+ w.fillRect(x1, y1, x2, h);
+ }
+}
+
+void dessineExplosion(DrawingWindow& w, float rx, float ry)
+{
+ const int maxray = rtowX(w, 5) - rtowX(w, 0);
+ // 1/2 rouge -> rouge -> jaune
+ const int x = rtowX(w, rx);
+ const int y = rtowY(w, ry);
+ int i;
+ for (i = 0; i <= maxray / 3; i++) {
+ w.setColor(0.5 + 3.0 * i / (2.0 * maxray), 0.0, 0.0);
+ w.drawCircle(x, y, i);
+ w.msleep(20);
+ }
+ for (/* i */; i < maxray; i++) {
+ w.setColor(1.0, 1.5 * i / maxray - 0.5, 0.0);
+ w.drawCircle(x, y, i);
+ w.msleep(20);
+ }
+ w.setColor("white");
+ for (i = 0; i < maxray; i++) {
+ w.drawCircle(x, y, i);
+ w.msleep(20);
+ }
+ w.fillCircle(x, y, maxray - 1);
+}
+
+void jeu(DrawingWindow& w)
+{
+ dessineTerrain(w, frand(largeurMin, largeurMax),
+ frand(hauteurMin, hauteurMax));
+ dessineChateau(w, positionChateau1);
+ dessineChateau(w, positionChateau2);
+
+ while (1)
+ dessineExplosion(w, frand(rXMin, rXMax), frand(rYMin, rYMax));
+
+}
+
+int main(int argc, char *argv[])
+{
+ QApplication application(argc, argv);
+ DrawingWindow window(jeu, 640, 480);
+ window.show();
+ return application.exec();
+}
+