root/src/examples/flowingcanvas/canvaswriter.h @ 170:f3ccf021e186

Revision 170:f3ccf021e186, 6.8 KB (checked in by Andreas Schaefer <gentryx@…>, 15 months ago)

experimenting with imitation of original image

Line 
1#ifndef _libgeodecomp_examples_flowingcanvas_canvaswriter_h_
2#define _libgeodecomp_examples_flowingcanvas_canvaswriter_h_
3
4#include <QtCore/qmath.h>
5#include <QImage>
6#include <QPainter>
7#include <libgeodecomp/io/writer.h>
8#include <libgeodecomp/examples/flowingcanvas/canvascell.h>
9
10namespace LibGeoDecomp {
11
12class CanvasWriter : public QObject, public Writer<CanvasCell>
13{
14    Q_OBJECT
15
16public:
17    class SelectForceFixed
18    {
19    public:
20        float operator()(const CanvasCell& cell, const int& index) const
21        {
22            return cell.forceFixed[index];
23        }
24    };
25
26    class SelectForceVario
27    {
28    public:
29        float operator()(const CanvasCell& cell, const int& index) const
30        {
31            return cell.forceVario[index];
32        }
33    };
34
35    class SelectForceTotal
36    {
37    public:
38        float operator()(const CanvasCell& cell, const int& index) const
39        {
40            return cell.forceTotal[index];
41        }
42    };
43
44    class SelectCameraLevel
45    {
46    public:
47        unsigned operator()(const CanvasCell& cell) const
48        {
49            return (0xff << 24) + ((int)(cell.cameraLevel * 250) << 16);
50        }
51    };
52
53    class SelectCameraPixel
54    {
55    public:
56        unsigned operator()(const CanvasCell& cell) const
57        {
58            return cell.cameraPixel;
59        }
60    };
61
62    class SelectOriginalPixel
63    {
64    public:
65        unsigned operator()(const CanvasCell& cell) const
66        {
67            return cell.originalPixel;
68        }
69    };
70
71    CanvasWriter(QImage **_outputFrame,
72                 MonolithicSimulator<CanvasCell> *_sim) :
73        Writer<CanvasCell>("foo", _sim, 1),
74        outputFrame(_outputFrame),
75        particleMode(3),
76        cameraMode(3)
77    {}
78
79    virtual void initialized()
80    {}
81
82    virtual void stepFinished()
83    {
84        const typename Simulator<CanvasCell>::GridType *grid = sim->getGrid();
85
86        switch (particleMode) {
87        case 0:
88            drawForce(grid, SelectForceVario());
89            break;
90        case 1:
91            drawForce(grid, SelectForceFixed());
92            break;
93        case 2:
94            drawForce(grid, SelectForceTotal());
95            break;
96        case 3:
97            drawParticles(grid);
98            break;
99        default:
100            break;
101        }
102
103        switch (cameraMode) {
104        case 0:
105            drawAttribute(grid, SelectOriginalPixel());
106            break;
107        case 1:
108            drawAttribute(grid, SelectCameraPixel());
109            break;
110        case 2:
111            drawAttribute(grid, SelectCameraLevel());
112            break;
113        default:
114            break;
115        }
116    }
117
118    virtual void allDone()
119    {
120    }
121
122public slots:
123    virtual void cycleViewModeParticle()
124    {
125        particleMode = (particleMode + 1) % 4;
126    }
127
128    virtual void cycleViewModeCamera()
129    {
130        cameraMode = (cameraMode + 1) % 4;
131    }
132
133private:
134    QImage **outputFrame;
135    int particleMode;
136    int cameraMode;
137
138    template<typename SELECTOR>
139    void drawForce(const typename Simulator<CanvasCell>::GridType *grid, const SELECTOR& selector)
140    {
141        Coord<2> dim = sim->getInitializer()->gridDimensions();
142       
143        int spacingX = 10;
144        int spacingY = 10;
145        float factorX = 1.0 * (*outputFrame)->width()  / dim.x();
146        float factorY = 1.0 * (*outputFrame)->height() / dim.y();
147
148        QPainter p(*outputFrame);
149        p.setBrush(QBrush(Qt::black));
150        p.drawRect(0, 0, (*outputFrame)->width(), (*outputFrame)->height());
151        p.setBrush(QBrush(Qt::white));
152        p.setPen(QPen(Qt::white));
153
154        for (int y = 0; y < dim.y(); y += spacingY) {
155            for (int x = 0; x < dim.x(); x += spacingX) {
156                int startX = (x + 0.5) * factorX;
157                int startY = (y + 0.5) * factorY;
158                const CanvasCell& cell = grid->at(Coord<2>(x, y));
159                float force0 = selector(cell, 0);
160                float force1 = selector(cell, 1);
161                int offsetX = force0 * spacingX * factorX * 0.8;
162                int offsetY = force1 * spacingY * factorY * 0.8;
163                int endX = startX + offsetX;
164                int endY = startY + offsetY;
165                p.drawLine(startX, startY, endX, endY); 
166                QRectF rect(endX - spacingX * 0.1, endY - spacingY * 0.1, spacingX * 0.2, spacingY * 0.2);
167                p.drawEllipse(rect);
168            }
169        }
170    }
171
172    // fixme: erase background
173    // fixme: scale to image size
174    template<typename SELECTOR>
175    void drawAttribute(const typename Simulator<CanvasCell>::GridType *grid, const SELECTOR& selector)
176    {
177        Coord<2> dim = sim->getInitializer()->gridDimensions();
178       
179        for (int y = 0; y < dim.y(); ++y) {
180            for (int x = 0; x < dim.x(); ++x) {
181                (*outputFrame)->setPixel(x, y, selector(grid->at(Coord<2>(x, y))));
182            }
183        }
184    }
185
186    void drawParticles(const typename Simulator<CanvasCell>::GridType *grid)
187    {
188        Coord<2> dim = sim->getInitializer()->gridDimensions();
189        float factorX = 1.0 * (*outputFrame)->width()  / dim.x();
190        float factorY = 1.0 * (*outputFrame)->height() / dim.y();
191
192        QPainter p(*outputFrame);
193        p.setBrush(QBrush(Qt::black));
194        p.drawRect(0, 0, (*outputFrame)->width(), (*outputFrame)->height());
195        p.setBrush(QBrush(Qt::white));
196        p.setPen(QPen(Qt::white));
197
198        QRect ellipse(-10, -3, 20, 6);
199        p.setPen(QPen(Qt::transparent));
200       
201        for (int y = 0; y < dim.y(); ++y) {
202            for (int x = 0; x < dim.x(); ++x) {
203                const CanvasCell& cell = grid->at(Coord<2>(x, y));
204                for (int i = 0; i < cell.numParticles; ++i) {
205                    const CanvasCell::Particle& particle = cell.particles[i];
206                    QPoint origin(particle.pos[0] * factorX,
207                                  particle.pos[1] * factorY);
208
209                    // double length = particle.vel[0] * particle.vel[0] + particle.vel[1] * particle.vel[1];
210                    // double angle = 0;
211
212                    // if (length > 0) {
213                    //     length = qSqrt(length);
214                    //     angle = (360.0 / 2.0 / 3.14159) * qAsin(particle.vel[1] / length);
215                    // }
216
217                    // p.save();
218                    // p.translate(origin);
219                    // p.rotate(angle);
220                    // p.setBrush(QBrush(particle.color));
221                    // p.drawEllipse(ellipse);
222
223                    // p.restore();
224
225                    QPoint direction(particle.vel[0] * 20,
226                                     particle.vel[1] * 20);
227                    QPoint end = origin + direction;
228                    QPoint offset(2, 2);
229                    QSize size(4, 4);
230                    QRectF rect(origin - offset, size);
231                    p.drawEllipse(rect);
232                    p.drawLine(origin, end);
233                }
234            }
235        }
236    }
237};
238
239}
240
241#endif
Note: See TracBrowser for help on using the browser.