18 #include <GL/freeglut.h>
20 #include "vector_view.h"
28 VectorView::VectorView(
const char* title, WinGeom* wg)
41 VectorView::VectorView(
char* title, WinGeom* wg)
54 VectorView::~VectorView()
59 void VectorView::show(MeshFunction<double>* vsln,
double eps)
63 if(vsln->get_num_components() < 2)
64 throw Hermes::Exceptions::Exception(
"The single-argument version of show() is only for vector-valued solutions.");
65 show(vsln, vsln, eps, H2D_FN_VAL_0, H2D_FN_VAL_1);
68 void VectorView::show(MeshFunction<double>* xsln, MeshFunction<double>* ysln,
double eps)
73 this->warn(
"Identical solutions passed to the two-argument version of show(). Most likely this is a mistake.");
74 show(xsln, ysln, eps, H2D_FN_VAL_0, H2D_FN_VAL_0);
77 void VectorView::show(MeshFunction<double>* xsln, MeshFunction<double>* ysln,
double eps,
int xitem,
int yitem)
83 vec->process_solution(xsln, ysln, xitem, yitem, eps);
86 range_min = vec->get_min_value();
87 range_max = vec->get_max_value();
89 vec->calc_vertices_aabb(&vertices_min_x, &vertices_max_x, &vertices_min_y, &vertices_max_y);
101 static int n_vert(
int i) {
return (i + 1) % 3; }
102 static int p_vert(
int i) {
return (i + 2) % 3; }
104 void VectorView::set_mode(
int mode)
106 this->mode = mode % 3;
115 void VectorView::plot_arrow(
double x,
double y,
double xval,
double yval,
double max,
double min,
double gs)
118 glColor3f(0.0f, 0.0f, 0.0f);
120 glColor3f(0.5f, 0.5f, 0.5f);
123 double Real_mag = sqrt(sqr(xval) + sqr(yval));
124 double mag = Real_mag;
125 if(Real_mag > max) mag = max;
126 double length = mag/max * gs * length_coef;
127 double width = 0.1 * gs;
128 if(mode == 1) width *= 1.2;
129 double xnew = x + gs * xval * mag / (max * Real_mag) * length_coef;
130 double ynew = y - gs * yval * mag / (max * Real_mag) * length_coef;
132 if((mag)/(max - min) < 1e-5)
134 glTranslated(x, y, 0.0);
137 glVertex2d( width, width);
138 glVertex2d( width, -width);
139 glVertex2d(-width, -width);
140 glVertex2d(-width, width);
147 glVertex2d(xnew, ynew);
150 glTranslated(x, y, 0.0);
151 glRotated(atan2(-yval, xval) * 180.0/M_PI, 0.0, 0.0, 1.0);
153 glBegin(GL_TRIANGLES);
154 glVertex2d(length + 3 * width, 0.0);
155 glVertex2d(length - 2 * width, width);
156 glVertex2d(length - 2 * width, -width);
165 get_palette_color((mag - min)/(max - min), color);
166 glColor3f(color[0], color[1], color[2]);
168 if(mag/(max - min) < 1e-5)
171 glVertex2d( width, width);
172 glVertex2d( width, -width);
173 glVertex2d(-width, -width);
174 glVertex2d(-width, width);
181 glVertex2d(xnew, ynew);
184 glTranslated(x - 1, y, 0.0);
185 glRotated(atan2(-yval, xval) * 180.0/M_PI, 0.0, 0.0, 1.0);
187 glBegin(GL_TRIANGLES);
188 glVertex2d(length + 3 * width, 0.0);
189 glVertex2d(length - 2 * width, width);
190 glVertex2d(length - 2 * width, -width);
198 void VectorView::on_display()
200 set_ortho_projection();
201 glDisable(GL_LIGHTING);
202 glDisable(GL_DEPTH_TEST);
203 glDisable(GL_TEXTURE_1D);
204 glPolygonMode(GL_FRONT_AND_BACK, pmode ? GL_LINE : GL_FILL);
208 if(hexa) gt *= sqrt(3.0)/2.0;
210 double max_length = 0.0;
215 int nv = vec->get_num_vertices();
216 double4* vert = vec->get_vertices();
217 double2* tvert =
new double2[nv];
219 for (i = 0; i < nv; i++)
221 tvert[i][0] = transform_x(vert[i][0]);
222 tvert[i][1] = transform_y(vert[i][1]);
225 double length = sqr(vert[i][2]) + sqr(vert[i][3]);
226 if(length > max_length) max_length = length;
228 max_length = sqrt(max_length);
231 double min = range_min, max = range_max;
232 if(range_auto) { min = vec->get_min_value(); max = vec->get_max_value(); }
233 double irange = 1.0 / (max - min);
235 if(fabs(min - max) < 1e-8) { irange = 1.0; min -= 0.5; }
238 int3* xtris = vec->get_triangles();
240 if(mode != 1) glEnable(GL_TEXTURE_1D);
241 glBindTexture(GL_TEXTURE_1D, gl_pallete_tex_id);
242 glBegin(GL_TRIANGLES);
243 glColor3f(0.95f, 0.95f, 0.95f);
244 for (i = 0; i < vec->get_num_triangles(); i++)
246 double mag = sqrt(sqr(vert[xtris[i][0]][2]) + sqr(vert[xtris[i][0]][3]));
247 glTexCoord2d((mag -min) * irange * tex_scale + tex_shift, 0.0);
248 glVertex2d(tvert[xtris[i][0]][0], tvert[xtris[i][0]][1]);
250 mag = sqrt(sqr(vert[xtris[i][1]][2]) + sqr(vert[xtris[i][1]][3]));
251 glTexCoord2d((mag -min) * irange * tex_scale + tex_shift, 0.0);
252 glVertex2d(tvert[xtris[i][1]][0], tvert[xtris[i][1]][1]);
254 mag = sqrt(sqr(vert[xtris[i][2]][2]) + sqr(vert[xtris[i][2]][3]));
255 glTexCoord2d((mag -min) * irange * tex_scale + tex_shift, 0.0);
256 glVertex2d(tvert[xtris[i][2]][0], tvert[xtris[i][2]][1]);
259 glDisable(GL_TEXTURE_1D);
263 glColor3f(0.5, 0.5, 0.5);
265 int2* edges = vec->get_edges();
266 for (i = 0; i < vec->get_num_edges(); i++)
268 if(lines || edges[i][2] != 0)
270 glVertex2d(tvert[edges[i][0]][0], tvert[edges[i][0]][1]);
271 glVertex2d(tvert[edges[i][1]][0], tvert[edges[i][1]][1]);
279 glEnable(GL_LINE_STIPPLE);
280 glLineStipple(1, 0xCCCC);
282 int2* dashes = vec->get_dashes();
283 for (i = 0; i < vec->get_num_dashes(); i++)
285 glVertex2d(tvert[dashes[i][0]][0], tvert[dashes[i][0]][1]);
286 glVertex2d(tvert[dashes[i][1]][0], tvert[dashes[i][1]][1]);
289 glDisable(GL_LINE_STIPPLE);
295 for (i = 0; i < vec->get_num_triangles(); i++)
298 int idx = -1, k, l1, l2, r2, r1, s;
300 double mr, ml, lx, rx, xval, yval;
302 double wh = output_height + gt, ww = output_width + gs;
303 if((tvert[xtris[i][0]][0] < -gs) && (tvert[xtris[i][1]][0] < -gs) && (tvert[xtris[i][2]][0] < -gs))
continue;
304 if((tvert[xtris[i][0]][0] > ww) && (tvert[xtris[i][1]][0] > ww) && (tvert[xtris[i][2]][0] > ww))
continue;
305 if((tvert[xtris[i][0]][1] < -gt) && (tvert[xtris[i][1]][1] < -gt) && (tvert[xtris[i][2]][1] < -gt))
continue;
306 if((tvert[xtris[i][0]][1] > wh) && (tvert[xtris[i][1]][1] > wh) && (tvert[xtris[i][2]][1] > wh))
continue;
309 for (k = 0; k < 3; k++)
310 if(tvert[xtris[i][k]][1] < miny)
311 miny = tvert[xtris[i][idx = k]][1];
312 l1 = r1 = xtris[i][idx];
313 l2 = xtris[i][n_vert(idx)];
314 r2 = xtris[i][p_vert(idx)];
317 double a[2], b[2], c[2], d[2];
318 for (
int n = 0; n < 2; n++)
320 a[n] = (tvert[l1][1] - tvert[l2][1])*(vert[r1][2 +n] - vert[r2][2 + n]) - (vert[l1][2 + n] - vert[l2][2 + n])*(tvert[r1][1] - tvert[r2][1]);
321 b[n] = (vert[l1][2 + n] - vert[l2][2 + n])*(tvert[r1][0] - tvert[r2][0]) - (tvert[l1][0] - tvert[l2][0])*(vert[r1][2 + n] - vert[r2][2 + n]);
322 c[n] = (tvert[l1][0] - tvert[l2][0])*(tvert[r1][1] - tvert[r2][1]) - (tvert[l1][1] - tvert[l2][1])*(tvert[r1][0] - tvert[r2][0]);
323 d[n] = -a[n] * tvert[l1][0] - b[n] * tvert[l1][1] - c[n] * vert[l1][2 + n];
324 a[n] /= c[n]; b[n] /= c[n]; d[n] /= c[n];
327 s = (int) ceil((tvert[l1][1] - gy)/gt);
329 bool shift = hexa && (s & 1);
332 if((tvert[l1][1] == tvert[l2][1]) || (tvert[r1][1] == tvert[r2][1]))
334 if(tvert[l1][1] == tvert[l2][1])
336 else if(tvert[r1][1] == tvert[r2][1])
341 ml = (tvert[l1][0] - tvert[l2][0])/(tvert[l1][1] - tvert[l2][1]);
342 mr = (tvert[r1][0] - tvert[r2][0])/(tvert[r1][1] - tvert[r2][1]);
344 lx = tvert[l1][0] + ml * (lry - (tvert[l1][1]));
345 rx = tvert[r1][0] + mr * (lry - (tvert[r1][1]));
349 k = (int) floor(-lry/gt);
356 while (((lry < tvert[l2][1]) || (lry < tvert[r2][1])) && (lry < wh))
359 while (((lry <= tvert[l2][1]) && (lry <= tvert[r2][1])) && (lry < wh))
362 if(shift) gz -= 0.5*gs;
363 s = (int) ceil((lx - gz)/gs);
365 if(hexa) shift = !shift;
369 k = (int) floor(-x/gs);
373 while ((x < rx) && (x < ww))
376 xval = -a[0]*x - b[0]*lry - d[0];
377 yval = -a[1]*x - b[1]*lry - d[1];
378 plot_arrow(x, lry, xval, yval, max, min, gs);
387 if(lry >= tvert[l2][1])
390 ml = (tvert[l1][0] - tvert[l2][0])/(tvert[l1][1] - tvert[l2][1]);
391 lx = tvert[l1][0] + ml * (lry - (tvert[l1][1]));
396 mr = (tvert[r1][0] - tvert[r2][0])/(tvert[r1][1] - tvert[r2][1]);
397 rx = tvert[r1][0] + mr * (lry - (tvert[r1][1]));
407 void VectorView::on_mouse_move(
int x,
int y)
414 View::on_mouse_move(x, y);
417 void VectorView::on_key_down(
unsigned char key,
int x,
int y)
437 set_palette_filter(pal_filter != GL_LINEAR);
441 set_grid_type(!hexa);
446 if(mode > 2) mode = 0;
452 if(key ==
'*') length_coef *= 1.1;
else length_coef /= 1.1;
457 View::on_key_down(key, x, y);
462 const char* VectorView::get_help_text()
const
467 " Left mouse - pan\n"
468 " Right mouse - zoom\n"
469 " B - toggle view mode (type of arrows x no arrows)\n"
470 " * - extend arrows\n"
471 " / - shorten arrows\n"
472 " C - center image\n"
473 " F - toggle smooth palette\n"
474 " X - toggle hexagonal grid\n"
475 " H - render high-quality frame\n"
477 " P - cycle palettes\n"
478 " S - save screenshot\n"