Orbiter 2022
Combinatorial Objects
graphical_output.cpp
Go to the documentation of this file.
1/*
2 * graphical_output.cpp
3 *
4 * Created on: Oct 11, 2020
5 * Author: betten
6 */
7
8#include "foundations.h"
9#include "EasyBMP.h"
10
11
12using namespace std;
13
14
15namespace orbiter {
16namespace layer1_foundations {
17namespace graphics {
18
19
20
21static int do_create_points_on_quartic_compute_point_function(double t,
22 double *pt, void *extra_data, int verbose_level);
23static int do_create_points_on_parabola_compute_point_function(double t,
24 double *pt, void *extra_data, int verbose_level);
25static int do_create_points_smooth_curve_compute_point_function(double t,
26 double *output, void *extra_data, int verbose_level);
27
28static std::vector<int> get_color(int bit_depth, int max_value, int loopCount, int f_invert_colors, int verbose_level);
29static void fillBitmap(BMP &image, int i, int j, std::vector<int> color);
30
31static void interface_povray_draw_frame(
32 animate *Anim, int h, int nb_frames, int round,
33 double clipping_radius,
34 std::ostream &fp,
35 int verbose_level);
36
37
39{
40
42 parabola_a = 0.;
43 parabola_b = 0.;
44 parabola_c = 0.;
45
46}
47
49{
50
51}
52
55 int verbose_level)
56{
57 int f_v = (verbose_level >= 1);
58
59 if (f_v) {
60 cout << "graphical_output::draw_layered_graph_from_file fname=" << fname << endl;
61 }
64
66 if (Fio.file_size(fname) <= 0) {
67 cout << "graphical_output::draw_layered_graph_from_file file " << fname << " does not exist" << endl;
68 exit(1);
69 }
70 LG->read_file(fname, verbose_level - 1);
71
72 if (f_v) {
73 cout << "graphical_output::draw_layered_graph_from_file Layered graph read from file" << endl;
74 }
75
77
78 int data1;
79
80
81 data1 = LG->data1;
82
83 if (f_v) {
84 cout << "graphical_output::draw_layered_graph_from_file data1=" << data1 << endl;
85 }
86
87 if (Opt->f_y_stretch) {
88 LG->place_with_y_stretch(Opt->y_stretch, verbose_level - 1);
89 }
90 if (Opt->f_spanning_tree) {
91 // create n e w x coordinates
92 LG->create_spanning_tree(TRUE /* f_place_x */, verbose_level);
93 }
94#if 0
95 if (Opt->f_numbering_on) {
96 // create depth first ranks at each node:
97 LG->create_spanning_tree(FALSE /* f_place_x */, verbose_level);
98 }
99#endif
100
101 if (Opt->f_x_stretch) {
102 LG->scale_x_coordinates(Opt->x_stretch, verbose_level);
103 }
104
105
106 string fname_out;
108
109 fname_out.assign(fname);
110 ST.chop_off_extension(fname_out);
111 fname_out.append("_draw");
112
113 //fname_out.append(".mp");
114
115 if (Opt->f_paths_in_between) {
116
117 if (f_v) {
118 cout << "graphical_output::draw_layered_graph_from_file f_paths_in_between" << endl;
119 }
120 std::vector<std::vector<int> > All_Paths;
121
122 if (f_v) {
123 cout << "graphical_output::draw_layered_graph_from_file before LG->find_all_paths_between" << endl;
124 }
125 LG->find_all_paths_between(Opt->layer1, Opt->node1, Opt->layer2, Opt->node2,
126 All_Paths,
127 verbose_level - 2);
128 if (f_v) {
129 cout << "graphical_output::draw_layered_graph_from_file after LG->find_all_paths_between" << endl;
130 }
131
132 if (f_v) {
133 cout << "graphical_output::draw_layered_graph_from_file before LG->remove_edges" << endl;
134 }
135 LG->remove_edges(Opt->layer1, Opt->node1, Opt->layer2, Opt->node2,
136 All_Paths,
137 verbose_level - 2);
138 if (f_v) {
139 cout << "graphical_output::draw_layered_graph_from_file after LG->remove_edges" << endl;
140 }
141
142
143 }
144
145 string fname_full;
146
147 fname_full.assign(fname_out);
148 fname_full.append(".mp");
149
150 LG->draw_with_options(fname_out, Opt, verbose_level - 10);
151
152 int n;
153 double avg;
154 n = LG->nb_nodes();
155 avg = LG->average_word_length();
156 if (f_v) {
157 cout << "graphical_output::draw_layered_graph_from_file "
158 "number of nodes = " << n << endl;
159 cout << "graphical_output::draw_layered_graph_from_file "
160 "average word length = " << avg << endl;
161 }
162
163
164 if (f_v) {
165 cout << "graphical_output::draw_layered_graph_from_file "
166 "Written file " << fname_full << " of size " << Fio.file_size(fname_full) << endl;
167 }
168
169 FREE_OBJECT(LG);
170
171 if (f_v) {
172 cout << "graphical_output::draw_layered_graph_from_file done" << endl;
173 }
174}
175
176void graphical_output::do_create_points_on_quartic(double desired_distance, int verbose_level)
177{
178 int f_v = (verbose_level >= 1);
179
180 if (f_v) {
181 cout << "graphical_output::do_create_points_on_quartic" << endl;
182 }
183
184 double amin, amid, amax;
185 //double epsilon = 0.001;
186 int N = 200;
187 int i;
188
189 //a0 = 16. / 25.;
190 //b0 = 16. / 25.;
191
192 amin = 0;
193 amid = 16. / 25.;
194 amax = 100;
195
196 int nb;
197
198 {
201
202 C1.init(2 /* nb_dimensions */,
203 desired_distance,
204 amin, amid,
205 do_create_points_on_quartic_compute_point_function,
206 this /* extra_data */,
207 100. /* boundary */,
208 N,
209 verbose_level);
210
211 cout << "after parametric_curve::init, C1.Pts.size()=" << C1.Pts.size() << endl;
212
213
214 C2.init(2 /* nb_dimensions */,
215 desired_distance,
216 amid, amax,
217 do_create_points_on_quartic_compute_point_function,
218 this /* extra_data */,
219 100. /* boundary */,
220 N,
221 verbose_level);
222
223 cout << "after parametric_curve::init, C2.Pts.size()=" << C2.Pts.size() << endl;
224
225
226 for (i = 0; i < (int) C1.Pts.size(); i++) {
227 cout << C1.Pts[i].t << " : " << C1.Pts[i].coords[0] << ", " << C1.Pts[i].coords[1] << endl;
228 }
229
230 double *Pts;
231 int nb_pts;
232
233 nb_pts = 4 * (C1.Pts.size() + C2.Pts.size());
234 Pts = new double[nb_pts * 2];
235 nb = 0;
236 for (i = 0; i < (int) C1.Pts.size(); i++) {
237 Pts[nb * 2 + 0] = C1.Pts[i].coords[0];
238 Pts[nb * 2 + 1] = C1.Pts[i].coords[1];
239 nb++;
240 }
241 for (i = 0; i < (int) C1.Pts.size(); i++) {
242 Pts[nb * 2 + 0] = -1 * C1.Pts[i].coords[0];
243 Pts[nb * 2 + 1] = C1.Pts[i].coords[1];
244 nb++;
245 }
246 for (i = 0; i < (int) C1.Pts.size(); i++) {
247 Pts[nb * 2 + 0] = C1.Pts[i].coords[0];
248 Pts[nb * 2 + 1] = -1 * C1.Pts[i].coords[1];
249 nb++;
250 }
251 for (i = 0; i < (int) C1.Pts.size(); i++) {
252 Pts[nb * 2 + 0] = -1 * C1.Pts[i].coords[0];
253 Pts[nb * 2 + 1] = -1 * C1.Pts[i].coords[1];
254 nb++;
255 }
256 for (i = 0; i < (int) C2.Pts.size(); i++) {
257 Pts[nb * 2 + 0] = C2.Pts[i].coords[0];
258 Pts[nb * 2 + 1] = C2.Pts[i].coords[1];
259 nb++;
260 }
261 for (i = 0; i < (int) C2.Pts.size(); i++) {
262 Pts[nb * 2 + 0] = -1 * C2.Pts[i].coords[0];
263 Pts[nb * 2 + 1] = C2.Pts[i].coords[1];
264 nb++;
265 }
266 for (i = 0; i < (int) C2.Pts.size(); i++) {
267 Pts[nb * 2 + 0] = C2.Pts[i].coords[0];
268 Pts[nb * 2 + 1] = -1 * C2.Pts[i].coords[1];
269 nb++;
270 }
271 for (i = 0; i < (int) C2.Pts.size(); i++) {
272 Pts[nb * 2 + 0] = -1 * C2.Pts[i].coords[0];
273 Pts[nb * 2 + 1] = -1 * C2.Pts[i].coords[1];
274 nb++;
275 }
277
278 string fname;
279
280 fname.assign("points.csv");
281
282 Fio.double_matrix_write_csv(fname, Pts, nb, 2);
283
284 cout << "created curve 1 with " << C1.Pts.size() << " many points" << endl;
285 cout << "created curve 2 with " << C2.Pts.size() << " many points" << endl;
286 }
287 cout << "created 4 curves with " << nb << " many points" << endl;
288
289
290
291 if (f_v) {
292 cout << "graphical_output::do_create_points_on_quartic done" << endl;
293 }
294}
295
297 double desired_distance, int N,
298 double a, double b, double c,
299 int verbose_level)
300{
301 int f_v = (verbose_level >= 1);
302
303 if (f_v) {
304 cout << "graphical_output::do_create_points_on_parabola" << endl;
305 }
306
307 double amin, amax;
308 double boundary;
309 int i;
310
311 amin = -10;
312 amax = 3.08;
313 boundary = 10;
314
315 int nb;
316
320
321 {
323
324 C.init(2 /* nb_dimensions */,
325 desired_distance,
326 amin, amax,
327 do_create_points_on_parabola_compute_point_function,
328 this /* extra_data */,
329 boundary,
330 N,
331 verbose_level);
332
333 cout << "after parametric_curve::init, C.Pts.size()=" << C.Pts.size() << endl;
334
335
336
337
338 for (i = 0; i < (int) C.Pts.size(); i++) {
339 cout << C.Pts[i].t << " : " << C.Pts[i].coords[0] << ", " << C.Pts[i].coords[1] << endl;
340 }
341
342 {
343 double *Pts;
344 int nb_pts;
345
346 nb_pts = C.Pts.size();
347 Pts = new double[nb_pts * 2];
348 nb = 0;
349 for (i = 0; i < (int) C.Pts.size(); i++) {
350 Pts[nb * 2 + 0] = C.Pts[i].coords[0];
351 Pts[nb * 2 + 1] = C.Pts[i].coords[1];
352 nb++;
353 }
355 char str[1000];
356 string fname;
357
358 snprintf(str, 1000, "parabola_N%d_%lf_%lf_%lf_points.csv", N, a, b, c);
359 fname.assign(str);
360
361 Fio.double_matrix_write_csv(fname, Pts, nb, 2);
362
363 cout << "created curve 1 with " << C.Pts.size() << " many points" << endl;
364 cout << "Written file " << fname << " of size " << Fio.file_size(fname) << endl;
365
366 delete [] Pts;
367 }
368
369 {
370 double *Pts;
371 int nb_pts;
372
373 nb_pts = C.Pts.size();
374 Pts = new double[nb_pts * 6];
375 nb = 0;
376 for (i = 0; i < (int) C.Pts.size(); i++) {
377 Pts[nb * 6 + 0] = C.Pts[i].coords[0];
378 Pts[nb * 6 + 1] = C.Pts[i].coords[1];
379 Pts[nb * 6 + 2] = 0.;
380 Pts[nb * 6 + 3] = 0.;
381 Pts[nb * 6 + 4] = 0.;
382 Pts[nb * 6 + 5] = 1.;
383 nb++;
384 }
386 char str[1000];
387 string fname;
388 snprintf(str, 1000, "parabola_N%d_%lf_%lf_%lf_projection_from_center.csv", N, a, b, c);
389 fname.assign(str);
390
391 Fio.double_matrix_write_csv(fname, Pts, nb, 6);
392
393 cout << "created family of lines 1 with " << C.Pts.size() << " many lines" << endl;
394 cout << "Written file " << fname << " of size " << Fio.file_size(fname) << endl;
395
396 delete [] Pts;
397 }
398
399 {
400 double *Pts;
401 int nb_pts;
402 double x, y, H, f;
403 double h = 1.;
404
405 nb_pts = C.Pts.size();
406 Pts = new double[nb_pts * 6];
407 nb = 0;
408 for (i = 0; i < (int) C.Pts.size(); i++) {
409 x = C.Pts[i].coords[0];
410 y = C.Pts[i].coords[1];
411 Pts[nb * 6 + 0] = x;
412 Pts[nb * 6 + 1] = y;
413 Pts[nb * 6 + 2] = 0.;
414
415 H = sqrt(h * h + x * x + y * y);
416 f = h / H;
417
418 Pts[nb * 6 + 3] = x * f;
419 Pts[nb * 6 + 4] = y * f;
420 Pts[nb * 6 + 5] = 1. - f;
421 nb++;
422 }
424
425 char str[1000];
426 string fname;
427 snprintf(str, 1000, "parabola_N%d_%lf_%lf_%lf_projection_from_sphere.csv", N, a, b, c);
428 fname.assign(str);
429
430
431 Fio.double_matrix_write_csv(fname, Pts, nb, 6);
432
433 cout << "created family of lines 1 with " << C.Pts.size() << " many lines" << endl;
434 cout << "Written file " << fname << " of size " << Fio.file_size(fname) << endl;
435
436 delete [] Pts;
437 }
438
439 {
440 double *Pts;
441 int nb_pts;
442 double x, y, H, f;
443 double h = 1.;
444
445 nb_pts = C.Pts.size();
446 Pts = new double[nb_pts * 3];
447 nb = 0;
448 for (i = 0; i < (int) C.Pts.size(); i++) {
449 x = C.Pts[i].coords[0];
450 y = C.Pts[i].coords[1];
451
452 H = sqrt(h * h + x * x + y * y);
453 f = h / H;
454
455 Pts[nb * 3 + 0] = x * f;
456 Pts[nb * 3 + 1] = y * f;
457 Pts[nb * 3 + 2] = 1. - f;
458 nb++;
459 }
461
462 char str[1000];
463 string fname;
464 snprintf(str, 1000, "parabola_N%d_%lf_%lf_%lf_points_projected.csv", N, a, b, c);
465 fname.assign(str);
466
467
468 Fio.double_matrix_write_csv(fname, Pts, nb, 3);
469
470 cout << "created family of lines 1 with " << C.Pts.size() << " many lines" << endl;
471 cout << "Written file " << fname << " of size " << Fio.file_size(fname) << endl;
472
473 delete [] Pts;
474 }
475
476
477 }
478 cout << "created curve with " << nb << " many points" << endl;
479
480
481
482 if (f_v) {
483 cout << "graphical_output::do_create_points_on_parabola done" << endl;
484 }
485}
486
487void graphical_output::do_smooth_curve(std::string &curve_label,
488 double desired_distance, int N,
489 double t_min, double t_max, double boundary,
490 function_polish_description *FP_descr, int verbose_level)
491{
492 int f_v = (verbose_level >= 1);
493 int nb_dimensions;
494
495 if (f_v) {
496 cout << "graphical_output::do_smooth_curve" << endl;
497 }
498
500
501 if (f_v) {
502 cout << "graphical_output::do_smooth_curve before smooth_curve_Polish->init" << endl;
503 }
504 smooth_curve_Polish->init(FP_descr, verbose_level);
505 if (f_v) {
506 cout << "graphical_output::do_smooth_curve after smooth_curve_Polish->init" << endl;
507 }
508#if 0
509 if (smooth_curve_Polish->Variables.size() != 1) {
510 cout << "interface_projective::do_smooth_curve number of variables should be 1, is "
511 << smooth_curve_Polish->Variables.size() << endl;
512 exit(1);
513 }
514#endif
515 nb_dimensions = smooth_curve_Polish->Entry.size();
516 if (f_v) {
517 cout << "graphical_output::do_smooth_curve nb_dimensions = " << nb_dimensions << endl;
518 }
519
520
521 {
523
524 C.init(nb_dimensions,
525 desired_distance,
526 t_min, t_max,
527 do_create_points_smooth_curve_compute_point_function,
528 this /* extra_data */,
529 boundary,
530 N,
531 verbose_level);
532
533 cout << "after parametric_curve::init, C.Pts.size()=" << C.Pts.size() << endl;
534
535 {
536 double *Pts;
537 int nb_pts;
538 int i, j, nb;
539
540 nb_pts = C.Pts.size();
541 Pts = new double[nb_pts * nb_dimensions];
542 nb = 0;
543 for (i = 0; i < (int) C.Pts.size(); i++) {
544 if (C.Pts[i].f_is_valid) {
545 for (j = 0; j < nb_dimensions; j++) {
546 Pts[nb * nb_dimensions + j] = C.Pts[i].coords[j];
547 }
548 nb++;
549 }
550 }
552
553 char str[1000];
554 string fname;
555 snprintf(str, 1000, "function_%s_N%d_points.csv", curve_label.c_str(), N);
556 fname.assign(str);
557
558
559 Fio.double_matrix_write_csv(fname, Pts, nb, nb_dimensions);
560
561 cout << "created curve 1 with " << C.Pts.size() << " many points" << endl;
562 cout << "Written file " << fname << " of size " << Fio.file_size(fname) << endl;
563
564 delete [] Pts;
565 }
566
567 {
568 double *Pts;
569 int nb_pts;
570 int i, j, nb, n;
571 double d; // euclidean distance to the previous point
572 numerics Num;
573
574 nb_pts = C.Pts.size();
575 n = 1 + nb_dimensions + 1;
576 Pts = new double[nb_pts * n];
577 nb = 0;
578 for (i = 0; i < (int) C.Pts.size(); i++) {
579 if (C.Pts[i].f_is_valid) {
580 Pts[nb * n + 0] = C.Pts[i].t;
581 for (j = 0; j < nb_dimensions; j++) {
582 Pts[nb * n + 1 + j] = C.Pts[i].coords[j];
583 }
584 if (nb) {
585 d = Num.distance_euclidean(Pts + (nb - 1) * n + 1, Pts + nb * n + 1, 3);
586 }
587 else {
588 d = 0;
589 }
590 Pts[nb * n + 1 + 4 + 0] = d;
591 nb++;
592 }
593 }
595
596 char str[1000];
597 string fname;
598 snprintf(str, 1000, "function_%s_N%d_points_plus.csv", curve_label.c_str(), N);
599 fname.assign(str);
600
601 Fio.double_matrix_write_csv(fname, Pts, nb, n);
602
603 cout << "created curve 1 with " << C.Pts.size() << " many points" << endl;
604 cout << "Written file " << fname << " of size " << Fio.file_size(fname) << endl;
605
606 delete [] Pts;
607 }
608
609 }
610
611 if (f_v) {
612 cout << "graphical_output::do_smooth_curve done" << endl;
613 }
614}
615
616
617//
618
619static int do_create_points_on_quartic_compute_point_function(double t,
620 double *pt, void *extra_data, int verbose_level)
621{
622 double num, denom, b;
623 double epsilon = 0.00001;
624
625 num = 4. - 4. * t;
626 denom = 4. - 25. * t * 0.25;
627 if (ABS(denom) < epsilon) {
628 return FALSE;
629 }
630 else {
631 b = num / denom;
632 if (b < 0) {
633 return FALSE;
634 }
635 else {
636 pt[0] = sqrt(t);
637 pt[1] = sqrt(b);
638 }
639 }
640 cout << "created point " << pt[0] << ", " << pt[1] << endl;
641 return TRUE;
642}
643
644static int do_create_points_on_parabola_compute_point_function(double t,
645 double *pt, void *extra_data, int verbose_level)
646{
647 graphical_output *I = (graphical_output *) extra_data;
648 double a = I->parabola_a;
649 double b = I->parabola_b;
650 double c = I->parabola_c;
651
652 pt[0] = t;
653 pt[1] = a * t * t + b * t + c;
654 //cout << "created point " << pt[0] << ", " << pt[1] << endl;
655 return TRUE;
656}
657
658
659static int do_create_points_smooth_curve_compute_point_function(double t,
660 double *output, void *extra_data, int verbose_level)
661{
662 int f_v = (verbose_level >= 1);
663 graphical_output *I = (graphical_output *) extra_data;
664 int ret = FALSE;
665 double epsilon = 0.0001;
666 double *input; // to store the input variable and all local variables during evaluate
667
668
669 if (f_v) {
670 cout << "do_create_points_smooth_curve_compute_point_function t = " << t << endl;
671 }
672 if (f_v) {
673 cout << "do_create_points_smooth_curve_compute_point_function before evaluate" << endl;
674 }
675 input = new double[I->smooth_curve_Polish->Variables.size()];
676 input[0] = t;
677 I->smooth_curve_Polish->evaluate(
678 input /* variable_values */,
679 output,
680 verbose_level);
681 delete [] input;
682
683 if (I->smooth_curve_Polish->Entry.size() == 4) {
684 if (ABS(output[3]) < epsilon) {
685 ret = FALSE;
686 }
687 else {
688 double av = 1. / output[3];
689 output[0] *= av;
690 output[1] *= av;
691 output[2] *= av;
692 output[3] *= av;
693 ret = TRUE;
694 }
695 }
696 else {
697 ret = TRUE;
698 }
699 if (f_v) {
700 cout << "do_create_points_smooth_curve_compute_point_function after evaluate t = " << t << endl;
701 }
702 return ret;
703}
704
706{
707 int f_v = (verbose_level >= 1);
708
709 if (f_v) {
710 cout << "graphical_output::draw_bitmap" << endl;
711 }
713
714
715 if (C->f_input_csv_file) {
716
718 C->M, C->m, C->n,
719 verbose_level);
720
722
723
724 int m, n;
725
726
728 C->M2, m, n,
729 verbose_level);
730 if (m != C->m) {
731 cout << "secondary matrix must have the same size as the primary input matrix" << endl;
732 exit(1);
733 }
734 if (n != C->n) {
735 cout << "secondary matrix must have the same size as the primary input matrix" << endl;
736 exit(1);
737 }
738 }
739
740 }
741 else {
742
743 }
744
745 if (f_v) {
746 cout << "graphical_output::draw_bitmap drawing matrix of size " << C->m << " x " << C->n << endl;
747 }
748
749 int *Row_parts = NULL;
750 int nb_row_parts = 0;
751 int *Col_parts = NULL;
752 int nb_col_parts = 0;
753
754
755 if (C->f_partition) {
756
757 orbiter_kernel_system::Orbiter->get_vector_from_label(C->part_row, Row_parts, nb_row_parts, 0 /* verbose_level*/);
758 orbiter_kernel_system::Orbiter->get_vector_from_label(C->part_col, Col_parts, nb_col_parts, 0 /* verbose_level*/);
759
760 cout << "row_part: ";
761 Int_vec_print(cout, Row_parts, nb_row_parts);
762 cout << endl;
763 cout << "col_part: ";
764 Int_vec_print(cout, Col_parts, nb_col_parts);
765 cout << endl;
766 }
767 int i;
768 int max_value;
770
771 max_value = orbiter_kernel_system::Orbiter->Int_vec->maximum(C->M, C->m * C->n);
772 cout << "max_value=" << max_value << endl;
773
774 //max_value += 5;
775 //cout << "max_value after adjustment=" << max_value << endl;
776
777
778 string fname_out;
779
780 if (C->f_input_csv_file) {
781 fname_out.assign(C->input_csv_file_name);
782 }
783 else {
784 fname_out.assign("bitmatrix.csv");
785
786 }
787 ST.replace_extension_with(fname_out, "_draw.bmp");
788
789 //int bit_depth = 8;
790
791 BMP image;
792
793 //int bit_depth = 24;
794
795
796 if (max_value > 10000) {
797 cout << "graphical_output::draw_bitmap max_value > 10000" << endl;
798 exit(1);
799 }
800 if (max_value == 0) {
801 max_value = 1;
802 }
803 for (i = max_value; i >= 0; i--) {
804 std::vector<int> color = get_color(C->bit_depth, max_value, i, C->f_invert_colors, 1);
805
806 cout << i << " : " << color[0] << "," << color[1] << "," << color[2] << endl;
807 }
808
809
810 int width, height;
811 //int *Table;
813
814 width = C->n;
815 height = C->m;
816
817 cout << "width=" << width << endl;
818
819 if (C->f_box_width) {
820 image.SetSize(width * C->box_width, height * C->box_width);
821 }
822 else {
823 image.SetSize(width, height);
824 }
825
826 image.SetBitDepth(C->bit_depth);
827
828 int j, d;
829 int N, N100, cnt;
830 int indent = 0;
831
832 N = height * width;
833 N100 = N / 100 + 1;
834
835 cout << "N100=" << N100 << endl;
836
837 cnt = 0;
838
840 indent = C->box_width >> 2;
841 }
842
843
844 std::vector<int> color_white = get_color(C->bit_depth, max_value, 0, C->f_invert_colors, 0);
845
846
847 for (i = 0; i < height; i++) {
848
849
850
851 for (j = 0; j < width; j++, cnt++) {
852
853
854 if ((cnt % N100) == 0) {
855 cout << "we are at " << ((double) cnt / (double) N) * 100. << " %" << endl;
856 }
857 d = C->M[i * width + j];
858 //std::vector<int> color = getColor(M[idx_x * width + idx_z]);
859 std::vector<int> color = get_color(C->bit_depth, max_value, d, C->f_invert_colors, 0);
860
861 // Here the pixel is set on the image.
862 if (C->f_box_width) {
863 int I, J, u, v;
864
865 I = i * C->box_width;
866 J = j * C->box_width;
867
869 if (C->M2[i * width + j] == 0) {
870 for (u = 0; u < C->box_width; u++) {
871 for (v = 0; v < C->box_width; v++) {
872 if (u < indent || u >= C->box_width - indent || v < indent || v >= C->box_width - indent) {
873 fillBitmap(image, J + v, I + u, color_white);
874 }
875 else {
876 fillBitmap(image, J + v, I + u, color);
877 }
878 }
879 }
880 }
881 else {
882 for (u = 0; u < C->box_width; u++) {
883 for (v = 0; v < C->box_width; v++) {
884 fillBitmap(image, J + v, I + u, color);
885 }
886 }
887 }
888 }
889 else {
890 for (u = 0; u < C->box_width; u++) {
891 for (v = 0; v < C->box_width; v++) {
892 fillBitmap(image, J + v, I + u, color);
893 }
894 }
895 }
896
897 }
898 else {
899 fillBitmap(image, j, i, color);
900 }
901 }
902 }
903 if (C->f_partition) {
904
905 cout << "drawing the partition" << endl;
906 int i0, j0;
907 int h, t, I, J;
908 std::vector<int> color = get_color(C->bit_depth, max_value, 1, C->f_invert_colors, 0);
909
910 // row partition:
911 i0 = 0;
912 for (h = 0; h <= nb_row_parts; h++) {
913 for (t = 0; t < C->part_width; t++) {
914 if (C->f_box_width) {
915 for (j = 0; j < width * C->box_width; j++) {
916 I = i0 * C->box_width;
917 if (h == nb_row_parts) {
918 fillBitmap(image, j, I - 1 - t, color);
919 }
920 else {
921 fillBitmap(image, j, I + t, color);
922 }
923 }
924 }
925 }
926 if (h < nb_row_parts) {
927 i0 += Row_parts[h];
928 }
929 }
930
931 // col partition:
932 j0 = 0;
933 for (h = 0; h <= nb_col_parts; h++) {
934 for (t = 0; t < C->part_width; t++) {
935 if (C->f_box_width) {
936 for (i = 0; i < height * C->box_width; i++) {
937 J = j0 * C->box_width;
938 if (h == nb_col_parts) {
939 fillBitmap(image, J - 1 - t, i, color);
940 }
941 else {
942 fillBitmap(image, J + t, i, color);
943 }
944 }
945 }
946 }
947 if (h < nb_col_parts) {
948 j0 += Col_parts[h];
949 }
950 }
951 }
952
953 cout << "before writing the image to file as " << fname_out << endl;
954
955 image.WriteToFile(fname_out.c_str());
956
957 std::cout << "Written file " << fname_out << std::endl;
958 {
960 cout << "Written file " << fname_out << " of size " << Fio.file_size(fname_out) << endl;
961 }
962
963
964
965
966 if (f_v) {
967 cout << "graphical_output::draw_bitmap done" << endl;
968 }
969
970}
971
972
974 layered_graph_draw_options *Opt, int verbose_level)
975{
976 int f_v = (verbose_level >= 1);
977
978 if (f_v) {
979 cout << "graphical_output::draw_projective_curve" << endl;
980 }
981
983 int t0 = Os.os_ticks();
984 //int xmax = Opt->xin; //1500;
985 //int ymax = Opt->yin; //1500;
986 int i;
987
988
989 if (Descr->f_animate) {
990
991 for (i = 0; i <= Descr->animate_nb_of_steps; i++) {
992
993
994 if (f_v) {
995 cout << "animate step " << i << " / " << Descr->animate_nb_of_steps << ":" << endl;
996 }
997 mp_graphics G;
998
999 char str[1000];
1000 string fname;
1001
1002 sprintf(str, "%s_%d_%d", Descr->fname.c_str(), Descr->number, i);
1003 fname.assign(str);
1004
1005 G.init(fname, Opt, verbose_level);
1006 //G.setup(fname, 0, 0, ONE_MILLION, ONE_MILLION,
1007 // xmax, ymax, Opt->f_embedded, Opt->f_sideways, Opt->scale, Opt->line_width, verbose_level - 1);
1008 //G.setup(fname2, 0, 0, ONE_MILLION, ONE_MILLION, xmax, ymax);
1009
1010
1011 //G.frame(0.05);
1012
1013
1014 draw_projective(G, Descr->number, i, Descr->animate_nb_of_steps, FALSE, 0, 0, FALSE, 0, FALSE, 0);
1015 G.finish(cout, TRUE);
1016
1017 }
1018 }
1019 else if (Descr->f_animate_with_transition) {
1020 int frame;
1021
1022 frame = 0;
1023
1024 if (Descr->f_title_page) {
1025
1026 for (i = 0; i < 4; i++, frame++) {
1027 mp_graphics G;
1028
1029 char str[1000];
1030 string fname;
1031
1032 sprintf(str, "%s_%d_%d", Descr->fname.c_str(), Descr->number, frame);
1033 fname.assign(str);
1034
1035 G.init(fname, Opt, verbose_level);
1036 //G.setup(fname, 0, 0, ONE_MILLION, ONE_MILLION,
1037 // xmax, ymax, Opt->f_embedded, Opt->f_sideways, Opt->scale, Opt->line_width,
1038 // verbose_level - 1);
1039
1041
1042
1043 G.finish(cout, TRUE);
1044
1045
1046 }
1047 }
1048
1049 for (i = 0; i <= Descr->animate_transition_nb_of_steps; i++, frame++) {
1050
1051 if (f_v) {
1052 cout << "frame " << frame << " transition in step " << i << " / " << Descr->animate_transition_nb_of_steps << ":" << endl;
1053 }
1054 mp_graphics G;
1055
1056 char str[1000];
1057 string fname;
1058
1059 sprintf(str, "%s_%d_%d", Descr->fname.c_str(), Descr->number, frame);
1060 fname.assign(str);
1061
1062 G.init(fname, Opt, verbose_level);
1063 //G.setup(fname, 0, 0, ONE_MILLION, ONE_MILLION,
1064 // xmax, ymax, Opt->f_embedded, Opt->f_sideways, Opt->scale, Opt->line_width,
1065 // verbose_level - 1);
1066 //G.setup(fname2, 0, 0, ONE_MILLION, ONE_MILLION, xmax, ymax);
1067
1068 //G.frame(0.05);
1069
1070
1072 G.finish(cout, TRUE);
1073
1074 }
1075
1076 for (i = 0; i <= Descr->animate_nb_of_steps; i++, frame++) {
1077
1078
1079 if (f_v) {
1080 cout << "frame " << frame << " animate step " << i << " / " << Descr->animate_nb_of_steps << ":" << endl;
1081 }
1082 mp_graphics G;
1083
1084 char str[1000];
1085 string fname;
1086
1087 sprintf(str, "%s_%d_%d", Descr->fname.c_str(), Descr->number, frame);
1088 fname.assign(str);
1089
1090 G.init(fname, Opt, verbose_level);
1091 //G.setup(fname, 0, 0, ONE_MILLION, ONE_MILLION,
1092 // xmax, ymax, Opt->f_embedded, Opt->f_sideways, Opt->scale, Opt->line_width,
1093 // verbose_level - 1);
1094 //G.setup(fname2, 0, 0, ONE_MILLION, ONE_MILLION, xmax, ymax);
1095
1096 //G.frame(0.05);
1097
1098
1099 draw_projective(G, Descr->number, i, Descr->animate_nb_of_steps, FALSE, 0, 0, FALSE, 0, FALSE, 0);
1100 G.finish(cout, TRUE);
1101
1102 }
1103
1104 for (i = 0; i <= Descr->animate_transition_nb_of_steps; i++, frame++) {
1105
1106 if (f_v) {
1107 cout << "frame " << frame << " transition in step " << i << " / " << Descr->animate_transition_nb_of_steps << ":" << endl;
1108 }
1109 mp_graphics G;
1110
1111 char str[1000];
1112 string fname;
1113
1114 sprintf(str, "%s_%d_%d", Descr->fname.c_str(), Descr->number, frame);
1115 fname.assign(str);
1116
1117 G.init(fname, Opt, verbose_level);
1118 //G.setup(fname, 0, 0, ONE_MILLION, ONE_MILLION,
1119 // xmax, ymax, Opt->f_embedded, Opt->f_sideways, Opt->scale, Opt->line_width,
1120 // verbose_level - 1);
1121 //G.setup(fname2, 0, 0, ONE_MILLION, ONE_MILLION, xmax, ymax);
1122
1123 //G.frame(0.05);
1124
1125
1126 draw_projective(G, Descr->number,
1129 FALSE, 0, FALSE, 0);
1130 G.finish(cout, TRUE);
1131
1132 }
1133 if (Descr->f_trailer_page) {
1134
1135 for (i = 0; i <= 7; i++, frame++) {
1136 mp_graphics G;
1137
1138 char str[1000];
1139 string fname;
1140
1141 sprintf(str, "%s_%d_%d", Descr->fname.c_str(), Descr->number, frame);
1142 fname.assign(str);
1143
1144 G.init(fname, Opt, verbose_level);
1145 //G.setup(fname, 0, 0, ONE_MILLION, ONE_MILLION,
1146 // xmax, ymax, Opt->f_embedded, Opt->f_sideways, Opt->scale, Opt->line_width,
1147 // verbose_level - 1);
1148
1149 draw_projective(G, Descr->number, 0,
1151 FALSE, 0, TRUE, i);
1152
1153
1154 G.finish(cout, TRUE);
1155
1156
1157 }
1158 }
1159
1160
1161 cout << "frame=" << frame << endl;
1162 }
1163
1164
1165
1166 Os.time_check(cout, t0);
1167 cout << endl;
1168}
1169
1170
1171
1173 int number, int animate_step, int animate_nb_of_steps,
1174 int f_transition, int transition_step, int transition_nb_steps,
1175 int f_title_page, int title_page_step,
1176 int f_trailer_page, int trailer_page_step)
1177{
1178 double *Dx, *Dy;
1179 int *Px, *Py;
1180 double x_stretch = 1.;
1181 double y_stretch = 1.;
1182 double dx = ONE_MILLION * 50 * x_stretch;
1183 double dy = ONE_MILLION * 50 * y_stretch; // stretch factor
1184 double x_labels_offset = -.5;
1185 double y_labels_offset = -.5;
1186 double x_tick_half_width = 0.1;
1187 double y_tick_half_width = 0.1;
1188 int N = 30;
1189 int i;
1190 double x_min = -10;
1191 double x_max = 10;
1192 double t_min = -1.13;
1193 double t_max = 5;
1194 double Delta_t;
1195 double step;
1196 double y_min = 0;
1197 double y_max = 2;
1198 double x, y, t;
1199 int subdivide_v = 4;
1200 int subdivide_h = 4;
1201 int f_plot_grid = TRUE;
1202 int f_plot_curve = TRUE;
1203 int x_mod = 1;
1204 int y_mod = 1;
1205 int x_tick_mod = 1;
1206 int y_tick_mod = 1;
1207 double height = 3.;
1208 double R, R2, X, Y;
1209 int mirror;
1210 int f_projection_on = TRUE;
1211 double radius = 10.;
1212 int N_curve = 500;
1213 numerics Num;
1214
1215
1216 cout << "draw_projective number=" << number << " animate_step=" << animate_step << " animate_nb_of_steps=" << animate_nb_of_steps << endl;
1217
1218 if (number == 1 || number == 3) {
1219 x_min = -10;
1220 x_max = 10;
1221 y_min = -10;
1222 y_max = 10;
1223 x_stretch = .7;
1224 y_stretch = .7;
1225 dx = ONE_MILLION * 50 * x_stretch;
1226 dy = ONE_MILLION * 50 * y_stretch; // stretch factor
1227 t_min = -1.119437527;
1228 t_max = 4;
1229 x_mod = 100;
1230 y_mod = 100;
1231 x_tick_mod = 1;
1232 y_tick_mod = 2;
1233 subdivide_v = 1;
1234 subdivide_h = 1;
1235 f_plot_curve = TRUE;
1236 x_labels_offset = -.5;
1237 y_labels_offset = -.5;
1238 x_tick_half_width = 0.2;
1239 y_tick_half_width = 0.1;
1240 f_plot_grid = TRUE;
1241 f_plot_curve = TRUE;
1242 height = 6;
1243 R = 20;
1244 f_projection_on = TRUE;
1245 radius = 10.;
1246 }
1247 else if (number == 2 || number == 4) {
1248 x_min = -10;
1249 x_max = 10;
1250 y_min = -10;
1251 y_max = 10;
1252 x_stretch = 0.25;
1253 y_stretch = 0.25;
1254 dx = ONE_MILLION * 50 * x_stretch;
1255 dy = ONE_MILLION * 50 * y_stretch; // stretch factor
1256 t_min = -1.119437527;
1257 t_max = 4;
1258 x_mod = 100;
1259 y_mod = 100;
1260 x_tick_mod = 1;
1261 y_tick_mod = 2;
1262 subdivide_v = 1;
1263 subdivide_h = 1;
1264 f_plot_curve = TRUE;
1265 x_labels_offset = -.5;
1266 y_labels_offset = -.5;
1267 x_tick_half_width = 0.2;
1268 y_tick_half_width = 0.1;
1269 f_plot_grid = TRUE;
1270 f_plot_curve = TRUE;
1271 height = 6;
1272 R = 20;
1273 f_projection_on = FALSE;
1274 radius = 10.;
1275 }
1276 else if (number == 5) {
1277 x_min = -10;
1278 x_max = 10;
1279 y_min = -10;
1280 y_max = 10;
1281 x_stretch = 0.25;
1282 y_stretch = 0.25;
1283 dx = ONE_MILLION * 50 * x_stretch;
1284 dy = ONE_MILLION * 50 * y_stretch; // stretch factor
1285 t_min = 0;
1286 t_max = 4;
1287 x_mod = 100;
1288 y_mod = 100;
1289 x_tick_mod = 1;
1290 y_tick_mod = 2;
1291 subdivide_v = 1;
1292 subdivide_h = 1;
1293 f_plot_curve = TRUE;
1294 x_labels_offset = -.5;
1295 y_labels_offset = -.5;
1296 x_tick_half_width = 0.2;
1297 y_tick_half_width = 0.1;
1298 f_plot_grid = TRUE;
1299 f_plot_curve = TRUE;
1300 height = 6;
1301 R = 20;
1302 f_projection_on = TRUE;
1303 radius = 10.;
1304 }
1305 else if (number == 7 || number == 8) {
1306 x_min = -10;
1307 x_max = 10;
1308 y_min = -10;
1309 y_max = 10;
1310 x_stretch = 0.25;
1311 y_stretch = 0.25;
1312 dx = ONE_MILLION * 50 * x_stretch;
1313 dy = ONE_MILLION * 50 * y_stretch; // stretch factor
1314 t_min = 0;
1315 t_max = 10;
1316 x_mod = 100;
1317 y_mod = 100;
1318 x_tick_mod = 1;
1319 y_tick_mod = 2;
1320 subdivide_v = 1;
1321 subdivide_h = 1;
1322 f_plot_curve = TRUE;
1323 x_labels_offset = -.5;
1324 y_labels_offset = -.5;
1325 x_tick_half_width = 0.2;
1326 y_tick_half_width = 0.1;
1327 f_plot_grid = TRUE;
1328 f_plot_curve = TRUE;
1329 height = 6;
1330 R = 20;
1331 if (number == 8) {
1332 f_projection_on = FALSE;
1333 }
1334 else {
1335 f_projection_on = TRUE;
1336 }
1337 radius = 10.;
1338 N_curve = 2000;
1339 }
1340
1341 Delta_t = t_max - t_min;
1342
1343 G.sl_thickness(100);
1344 //G.sf_color(1);
1345 //G.sf_interior(10);
1346 Px = new int[N];
1347 Py = new int[N];
1348 Dx = new double[N];
1349 Dy = new double[N];
1350
1351
1352 cout << "draw_projective dx=" << dx << " dy=" << dy << endl;
1353
1354 double box_x_min = x_min * 1.2;
1355 double box_x_max = x_max * 1.2;
1356 double box_y_min = y_min * 1.2;
1357 double box_y_max = y_max * 1.2;
1358
1359 // draw a black frame:
1360 Dx[0] = box_x_min;
1361 Dy[0] = box_y_min;
1362 Dx[1] = box_x_max;
1363 Dy[1] = box_y_min;
1364 Dx[2] = box_x_max;
1365 Dy[2] = box_y_max;
1366 Dx[3] = box_x_min;
1367 Dy[3] = box_y_max;
1368 for (i = 0; i < 4; i++) {
1369 //project_to_disc(f_projection_on, radius, height, Dx[i], Dy[i], Dx[i], Dy[i]);
1370 Px[i] = Dx[i] * dx;
1371 Py[i] = Dy[i] * dy;
1372 }
1373 G.polygon5(Px, Py, 0, 1, 2, 3, 0);
1374
1375
1376 if (f_title_page) {
1377
1378 X = 0;
1379 Y = 9;
1380 for (i = 0; i < 11; i++) {
1381 Dx[i] = X;
1382 Dy[i] = Y;
1383 Y = Y - 1.8;
1384 }
1385
1386 for (i = 0; i < 11; i++) {
1387 Px[i] = Dx[i] * dx;
1388 Py[i] = Dy[i] * dy;
1389 }
1390
1391 G.aligned_text_array(Px, Py, 0, "", "Transforming a Parabola");
1392 G.aligned_text_array(Px, Py, 1, "", "into a Hyperbola");
1393 if (title_page_step == 0) {
1394 return;
1395 }
1396 G.aligned_text_array(Px, Py, 4, "", "Step 1: Move into");
1397 G.aligned_text_array(Px, Py, 5, "", "the projective plane");
1398 if (title_page_step == 1) {
1399 return;
1400 }
1401 G.aligned_text_array(Px, Py, 6, "", "Step 2: Transform the equation");
1402 if (title_page_step == 2) {
1403 return;
1404 }
1405 G.aligned_text_array(Px, Py, 7, "", "Step 3: Move back");
1406 G.aligned_text_array(Px, Py, 8, "", "in the affine plane");
1407 if (title_page_step == 3) {
1408 return;
1409 }
1410 G.aligned_text_array(Px, Py, 10, "", "Created by Anton Betten 2017");
1411 return;
1412
1413 }
1414
1415
1416 if (f_trailer_page) {
1417
1418 X = 0;
1419 Y = 9.5;
1420 for (i = 0; i < 18; i++) {
1421 Dx[i] = X;
1422 Dy[i] = Y;
1423 Y = Y - 1.4;
1424 }
1425
1426 for (i = 0; i < 18; i++) {
1427 Px[i] = Dx[i] * dx;
1428 Py[i] = Dy[i] * dy;
1429 }
1430
1431 G.aligned_text_array(Px, Py, 0, "", "Thanks for watching!");
1432 if (trailer_page_step == 0) {
1433 return;
1434 }
1435 G.aligned_text_array(Px, Py, 2, "", "credits:");
1436 if (trailer_page_step == 1) {
1437 return;
1438 }
1439 G.aligned_text_array(Px, Py, 4, "", "Felix Klein:");
1440 if (trailer_page_step == 2) {
1441 return;
1442 }
1443 G.aligned_text_array(Px, Py, 5, "", "Introduction to");
1444 G.aligned_text_array(Px, Py, 6, "", "non-euclidean geometry");
1445 G.aligned_text_array(Px, Py, 7, "", "(in German) 1928");
1446 if (trailer_page_step == 3) {
1447 return;
1448 }
1449 G.aligned_text_array(Px, Py, 9, "", "Latex: Donald Knuth");
1450 G.aligned_text_array(Px, Py, 10, "", "Leslie Lamport");
1451 if (trailer_page_step == 4) {
1452 return;
1453 }
1454 G.aligned_text_array(Px, Py, 11, "", "Tikz: Till Tantau");
1455 if (trailer_page_step == 5) {
1456 return;
1457 }
1458 G.aligned_text_array(Px, Py, 12, "", "ImageMagick Studio LLC");
1459 if (trailer_page_step == 6) {
1460 return;
1461 }
1462 G.aligned_text_array(Px, Py, 14, "", "Created by Anton Betten 2017");
1463 return;
1464
1465 }
1466
1467#if 1
1468 if (f_plot_grid) {
1469
1470 int *f_DNE;
1471
1472 f_DNE = NEW_int(N);
1473
1474
1475 G.sl_thickness(10);
1476
1477 for (x = 0; x < R; x++) {
1478
1479 for (mirror = 0; mirror < 2; mirror++) {
1480 R2 = sqrt(R * R - x * x);
1481
1482 // vertical line:
1483 t_min = -R2;
1484 t_max = R2;
1485
1486 Delta_t = t_max - t_min;
1487 step = Delta_t / (double) N;
1488
1489 for (i = 0; i < N; i++) {
1490 f_DNE[i] = FALSE;
1491 t = t_min + i * step;
1492
1493
1494 if (mirror == 0) {
1495 X = x;
1496 Y = t;
1497 }
1498 else {
1499 X = -x;
1500 Y = t;
1501 }
1502
1503
1504 if (f_DNE[i] == FALSE) {
1505 Dx[i] = X;
1506 Dy[i] = Y;
1507 Num.project_to_disc(f_projection_on, f_transition, transition_step, transition_nb_steps, radius, height, Dx[i], Dy[i], Dx[i], Dy[i]);
1508 if (Dx[i] < box_x_min || Dx[i] > box_x_max || Dy[i] < box_y_min || Dy[i] > box_y_max) {
1509 f_DNE[i] = TRUE;
1510 }
1511 }
1512 }
1513 G.plot_curve(N, f_DNE, Dx, Dy, dx, dy);
1514 }
1515 }
1516 for (y = 0; y < R; y++) {
1517
1518 for (mirror = 0; mirror < 2; mirror++) {
1519 R2 = sqrt(R * R - y * y);
1520
1521 // horizontal line:
1522 t_min = -R2;
1523 t_max = R2;
1524
1525 Delta_t = t_max - t_min;
1526 step = Delta_t / (double) N;
1527
1528 for (i = 0; i < N; i++) {
1529 f_DNE[i] = FALSE;
1530 t = t_min + i * step;
1531
1532
1533 if (mirror == 0) {
1534 X = t;
1535 Y = y;
1536 }
1537 else {
1538 X = t;
1539 Y = -y;
1540 }
1541
1542
1543 if (f_DNE[i] == FALSE) {
1544 Dx[i] = X;
1545 Dy[i] = Y;
1546 Num.project_to_disc(f_projection_on, f_transition, transition_step, transition_nb_steps, radius, height, Dx[i], Dy[i], Dx[i], Dy[i]);
1547 if (Dx[i] < box_x_min || Dx[i] > box_x_max || Dy[i] < box_y_min || Dy[i] > box_y_max) {
1548 f_DNE[i] = TRUE;
1549 }
1550 }
1551 }
1552 G.plot_curve(N, f_DNE, Dx, Dy, dx, dy);
1553 }
1554 }
1555
1556 FREE_int(f_DNE);
1557 }
1558#endif
1559
1560 if (f_plot_curve) {
1561
1562
1563 G.sl_color(2);
1564
1565 double omega;
1566
1567 omega = -1 * animate_step * M_PI / (2 * animate_nb_of_steps);
1568 cout << "animate_step=" << animate_step << " omega=" << omega << endl;
1569 double cos_omega, sin_omega;
1570
1571 cos_omega = cos(omega);
1572 sin_omega = sin(omega);
1573 cout << "sin_omega=" << sin_omega << " cos_omega=" << cos_omega << endl;
1574
1575 N = N_curve;
1576
1577 delete [] Px;
1578 delete [] Py;
1579 delete [] Dx;
1580 delete [] Dy;
1581
1582 int *f_DNE;
1583
1584 f_DNE = NEW_int(N);
1585 Px = new int[N];
1586 Py = new int[N];
1587 Dx = new double[N];
1588 Dy = new double[N];
1589
1590
1591 G.sl_thickness(100);
1592
1593 // draw the function as a parametric curve:
1594
1595 double s_min, s_max, s, Delta_s;
1596 int h;
1597
1598 for (h = 0; h < 2; h++) {
1599 if (number == 1 || number == 2) {
1600 s_min = 0;
1601 }
1602 else if (number == 5) {
1603 s_min = -30;
1604 }
1605 else if (number == 7 || number == 8) {
1606 s_min = -30;
1607 }
1608 else {
1609 s_min = -1.119437527;
1610 }
1611 s_max = 30;
1612
1613 //t_min = -R;
1614 //t_max = R;
1615
1616 //Delta_t = t_max - t_min;
1617 Delta_s = s_max - s_min;
1618 step = Delta_s / (double) N;
1619
1620 cout << "Delta_s=" << Delta_s << " step=" << step << endl;
1621 cout << "draw_projective dx=" << dx << " dy=" << dy << endl;
1622
1623 for (i = 0; i < N; i++) {
1624
1625
1626 f_DNE[i] = FALSE;
1627
1628 s = exp(s_min + i * step);
1629 // this allows us to get many very small values and many very big values as well.
1630
1631#if 0
1632 if (f_projection_on) {
1633 if (s > 10) {
1634 s = 10 + exp(s - 10);
1635 }
1636 }
1637#endif
1638 t = s;
1639 //t = exp(s);
1640 //t = t_min + i * step;
1641
1642 //cout << "i=" << i << " s=" << s << " t=" << t << endl;
1643
1644
1645 if (number == 1 || number == 2) {
1646 X = t;
1647 Y = t * t;
1648 }
1649 else if (number == 3 || number == 4) {
1650 X = t;
1651 Y = t * t * t + 5 * t + 7;
1652 if (Y < 0) {
1653 f_DNE[i] = TRUE;
1654 }
1655 else {
1656 Y = sqrt(Y);
1657 }
1658 }
1659 else if (number == 5) {
1660 double denom, x, y;
1661 x = t;
1662 y = t * t;
1663 denom = x * sin_omega + cos_omega;
1664
1665 if (ABS(denom) < 0.0000000001) {
1666 f_DNE[i] = TRUE;
1667 }
1668 else {
1669 if (h == 0) {
1670 X = (x * cos_omega - sin_omega) / denom;
1671 }
1672 else {
1673 X = (-x * cos_omega - sin_omega) / denom;
1674 }
1675 Y = y / denom;
1676 }
1677 }
1678 else if (number == 7 || number == 8) {
1679 X = t;
1680 if (t < 0) {
1681 f_DNE[i] = TRUE;
1682 }
1683 else {
1684 Y = log(t);
1685 if (ABS(Y) < 0.0001) {
1686 f_DNE[i] = TRUE;
1687 }
1688 }
1689 }
1690
1691#if 0
1692 if (!f_DNE[i]) {
1693 double z;
1694
1695 z = sqrt(X * X + Y * Y);
1696 if (z > 2 * R) {
1697 f_DNE[i] = TRUE;
1698 //cout << endl;
1699 //cout << "x=" << x << " y=" << y << " is out of bounds" << endl;
1700 }
1701 }
1702#endif
1703
1704#if 0
1705 cout << "i=" << i << " s=" << s << " t=" << t << " f_DNE[i]=" << f_DNE[i];
1706 if (f_DNE[i] == FALSE) {
1707 cout << " X=" << X << " Y=" << Y << endl;
1708 }
1709 else {
1710 cout << endl;
1711 }
1712#endif
1713
1714 if (f_DNE[i] == FALSE) {
1715 //double z;
1716
1717 Dx[i] = X;
1718 Dy[i] = Y;
1719#if 0
1720 if (animate_step == 8) {
1721 cout << "X=" << X << " Y=" << Y << endl;
1722 }
1723#endif
1724 Num.project_to_disc(f_projection_on, f_transition, transition_step, transition_nb_steps, radius, height, Dx[i], Dy[i], Dx[i], Dy[i]);
1725
1726 //z = sqrt(Dx[i] * Dx[i] + Dy[i] * Dy[i]);
1727 if (Dx[i] < box_x_min || Dx[i] > box_x_max || Dy[i] < box_y_min || Dy[i] > box_y_max) {
1728 f_DNE[i] = TRUE;
1729 //cout << endl;
1730 //cout << "x=" << x << " y=" << y << " is out of bounds" << endl;
1731 }
1732 if (!f_DNE[i] && isnan(Dx[i])) {
1733 f_DNE[i] = TRUE;
1734 }
1735 if (!f_DNE[i] && isnan(Dy[i])) {
1736 f_DNE[i] = TRUE;
1737 }
1738 if (!f_DNE[i] && ABS(Dx[i]) < 0.0001) {
1739 f_DNE[i] = TRUE;
1740 }
1741 if (!f_DNE[i] && ABS(Dy[i]) < 0.0001) {
1742 f_DNE[i] = TRUE;
1743 }
1744 }
1745 cout << i << " : s=" << s << " : " << " : t=" << t << " : ";
1746 if (f_DNE[i]) {
1747 cout << "-";
1748 }
1749 else {
1750 cout << Dx[i] << ", " << Dy[i];
1751 }
1752 cout << endl;
1753 }
1754
1755 if (FALSE) {
1756 cout << "before plot_curve:" << endl;
1757 for (i = 0; i < N; i++) {
1758 cout << i << " : ";
1759 if (f_DNE[i]) {
1760 cout << "-";
1761 }
1762 else {
1763 cout << Dx[i] << ", " << Dy[i];
1764 }
1765 cout << endl;
1766 }
1767 }
1768
1769 G.plot_curve(N, f_DNE, Dx, Dy, dx, dy);
1770 } // next h
1771
1772
1773 FREE_int(f_DNE);
1774 }
1775
1776
1777}
1778
1779
1780
1781
1782std::vector<int> get_color(int bit_depth, int max_value, int loopCount, int f_invert_colors, int verbose_level)
1783{
1784 int f_v = (verbose_level>= 1);
1785 int r, g, b;
1786#if 0
1787 Black #000000 (0,0,0)
1788 White #FFFFFF (255,255,255)
1789 Red #FF0000 (255,0,0)
1790 Lime #00FF00 (0,255,0)
1791 Blue #0000FF (0,0,255)
1792 Yellow #FFFF00 (255,255,0)
1793 Cyan / Aqua #00FFFF (0,255,255)
1794 Magenta / Fuchsia #FF00FF (255,0,255)
1795 Silver #C0C0C0 (192,192,192)
1796 Gray #808080 (128,128,128)
1797 Maroon #800000 (128,0,0)
1798 Olive #808000 (128,128,0)
1799 Green #008000 (0,128,0)
1800 Purple #800080 (128,0,128)
1801 Teal #008080 (0,128,128)
1802 Navy #000080 (0,0,128)
1803#endif
1804 int table[] = {
1805 255,255,255, // white
1806 0,0,0, // black
1807 255,0,0,
1808 0,255,0,
1809 0,0,255,
1810 255,255,0,
1811 0,255,255,
1812 255,0,255,
1813 192,192,192,
1814 128,128,128,
1815 128,0,0,
1816 128,128,0,
1817 0,128,0,
1818 128,0,128,
1819 0,128,128,
1820 0,0,128
1821 };
1822
1823
1824 if (loopCount < 16 && bit_depth == 8) {
1825 r = table[loopCount * 3 + 0];
1826 g = table[loopCount * 3 + 1];
1827 b = table[loopCount * 3 + 2];
1828 }
1829 else {
1830 double a1, a2, x, y, z;
1831 int max_color;
1832
1833 max_color = (1 << bit_depth) - 1;
1834
1835 if (loopCount > max_value) {
1836 cout << "loopCount > max_value" << endl;
1837 cout << "loopCount=" << loopCount << endl;
1838 cout << "max_value=" << max_value << endl;
1839 exit(1);
1840 }
1841
1842 if (loopCount < 16) {
1843 r = table[loopCount * 3 + 0];
1844 g = table[loopCount * 3 + 1];
1845 b = table[loopCount * 3 + 2];
1846 return { r, g, b};
1847 }
1848 loopCount -= 16;
1849
1850 a1 = (double) loopCount / (double) max_value;
1851
1852
1853 if (f_invert_colors) {
1854 a2 = 1. - a1;
1855 }
1856 else {
1857 a2 = a1;
1858 }
1859 x = a2;
1860 y = a2 * a2;
1861 z = y * a2;
1862 r = x * max_color;
1863 g = y * max_color;
1864 b = z * max_color;
1865 if (f_v) {
1866 cout << loopCount << " : " << max_value << " : "
1867 << a1 << " : " << a2 << " : " << x << "," << y << "," << z << " : " << r << "," << g << "," << b << endl;
1868 }
1869 }
1870 return { r, g, b};
1871}
1872
1873void fillBitmap(BMP &image, int i, int j, std::vector<int> color)
1874{
1875 // The pixel is set using its image
1876 // location and stacks 3 variables (RGB) into the vector word.
1877 image(i, j)->Red = color[0];
1878 image(i, j)->Green = color[1];
1879 image(i, j)->Blue = color[2];
1880};
1881
1882void graphical_output::tree_draw(tree_draw_options *Tree_draw_options, int verbose_level)
1883{
1884 int f_v = (verbose_level >= 1);
1885
1886 if (f_v) {
1887 cout << "graphical_output::tree_draw" << endl;
1888 }
1889
1890 if (!Tree_draw_options->f_file) {
1891 cout << "graphical_output::tree_draw please use -file <fname>" << endl;
1892 exit(1);
1893 }
1894 tree T;
1896 std::string fname2;
1897
1898 cout << "Trying to read file " << Tree_draw_options->file_name << " of size "
1899 << Fio.file_size(Tree_draw_options->file_name) << endl;
1900
1901 if (Fio.file_size(Tree_draw_options->file_name) <= 0) {
1902 cout << "treedraw.out the input file " << Tree_draw_options->file_name
1903 << " does not exist" << endl;
1904 exit(1);
1905 }
1906
1907 if (f_v) {
1908 cout << "graphical_output::tree_draw reading input file " << Tree_draw_options->file_name << endl;
1909 }
1910 T.init(Tree_draw_options,
1911 orbiter_kernel_system::Orbiter->draw_options->xin,
1913 verbose_level);
1914 if (f_v) {
1915 cout << "graphical_output::tree_draw reading input file " << Tree_draw_options->file_name << " finished" << endl;
1916 }
1917
1918#if 0
1919 if (/* T.nb_nodes > 200 ||*/ f_no_circletext) {
1920 f_circletext = FALSE;
1921 }
1922 if (f_on_circle) {
1923 T.root->place_on_circle(xmax, ymax, T.max_depth);
1924 }
1925
1926 if (f_count_leaves) {
1927 T.f_count_leaves = TRUE;
1928 }
1929#endif
1930
1932
1933 fname2.assign(Tree_draw_options->file_name);
1934 ST.chop_off_extension(fname2);
1935 fname2.append("_draw");
1936
1937 if (f_v) {
1938 cout << "graphical_output::tree_draw before T.draw" << endl;
1939 }
1940 T.draw(fname2,
1941 Tree_draw_options,
1942 orbiter_kernel_system::Orbiter->draw_options,
1943 verbose_level);
1944 if (f_v) {
1945 cout << "graphical_output::tree_draw after T.draw" << endl;
1946 }
1947
1948#if 0
1949 if (f_graph) {
1950 cout << "treedraw.out drawing as graph" << endl;
1951 T.draw(fname_out,
1952 xmax, ymax, xmax_out, ymax_out, rad, f_circle, f_circletext,
1953 f_i, f_e, TRUE, draw_vertex_callback,
1954 f_embedded, f_sideways, f_on_circle,
1955 scale, line_width, verbose_level - 1);
1956 }
1957 else if (f_placeholder_labels) {
1958 T.draw(fname_out,
1959 xmax, ymax, xmax_out, ymax_out, rad, f_circle, f_circletext,
1960 f_i, f_e, TRUE, draw_vertex_callback_placeholders,
1961 f_embedded, f_sideways, f_on_circle,
1962 scale, line_width, verbose_level - 1);
1963 }
1964 else {
1965 T.draw(fname_out,
1966 xmax, ymax, xmax_out, ymax_out, rad, f_circle, f_circletext,
1967 f_i, f_e, TRUE, draw_vertex_callback_standard,
1968 f_embedded, f_sideways, f_on_circle,
1969 scale, line_width, verbose_level - 1);
1970 }
1971#endif
1972 if (f_v) {
1973 cout << "graphical_output::tree_draw done" << endl;
1974 }
1975
1976}
1977
1978
1979
1980
1981
1983 povray_job_description *Povray_job_description,
1984 int verbose_level)
1985{
1986 int f_v = (verbose_level >= 1);
1987
1988 if (f_v) {
1989 cout << "graphical_output::animate_povray" << endl;
1990 }
1991 animate *A;
1992
1993 A = NEW_OBJECT(animate);
1994
1995 A->init(Povray_job_description,
1996 NULL /* extra_data */,
1997 verbose_level);
1998
1999
2000 A->draw_frame_callback = interface_povray_draw_frame;
2001
2002
2003
2004
2005
2006
2007
2008 //char fname_makefile[1000];
2009
2010
2011 //sprintf(fname_makefile, "makefile_animation");
2012
2013 {
2014 ofstream fpm(A->fname_makefile);
2015
2016 A->fpm = &fpm;
2017
2018 fpm << "all:" << endl;
2019
2020 if (Povray_job_description->f_rounds) {
2021
2022 int *rounds;
2023 int nb_rounds;
2024
2025 Int_vec_scan(Povray_job_description->rounds_as_string, rounds, nb_rounds);
2026
2027 cout << "Doing the following " << nb_rounds << " rounds: ";
2028 Int_vec_print(cout, rounds, nb_rounds);
2029 cout << endl;
2030
2031 int r, this_round;
2032
2033 for (r = 0; r < nb_rounds; r++) {
2034
2035
2036 this_round = rounds[r];
2037
2038 cout << "round " << r << " / " << nb_rounds
2039 << " is " << this_round << endl;
2040
2041 //round = first_round + r;
2042
2044 this_round,
2045 verbose_level);
2046
2047 }
2048 }
2049 else {
2050 cout << "round " << Povray_job_description->round << endl;
2051
2052
2054 Povray_job_description->round,
2055 verbose_level);
2056
2057 }
2058
2059 fpm << endl;
2060 }
2062
2063 cout << "Written file " << A->fname_makefile << " of size "
2064 << Fio.file_size(A->fname_makefile) << endl;
2065
2066
2067
2068 FREE_OBJECT(A);
2069 A = NULL;
2070
2071}
2072
2073
2074static void interface_povray_draw_frame(
2075 animate *Anim, int h, int nb_frames, int round,
2076 double clipping_radius,
2077 ostream &fp,
2078 int verbose_level)
2079{
2080 int i, j;
2081
2082
2083
2084 Anim->Pov->union_start(fp);
2085
2086
2087 if (round == 0) {
2088
2089
2090 for (i = 0; i < (int) Anim->S->Drawables.size(); i++) {
2092 int f_group_is_animated = FALSE;
2093
2094 if (FALSE) {
2095 cout << "drawable " << i << ":" << endl;
2096 }
2097 D = Anim->S->Drawables[i];
2098
2099 for (j = 0; j < Anim->S->animated_groups.size(); j++) {
2100 if (Anim->S->animated_groups[j] == i) {
2101 break;
2102 }
2103 }
2104 if (j < Anim->S->animated_groups.size()) {
2105 f_group_is_animated = TRUE;
2106 }
2107 if (FALSE) {
2108 if (f_group_is_animated) {
2109 cout << "is animated" << endl;
2110 }
2111 else {
2112 cout << "is not animated" << endl;
2113 }
2114 }
2115 D.draw(Anim, fp, f_group_is_animated, h, verbose_level);
2116 }
2117
2118
2119 }
2120
2121 //Anim->S->clipping_by_cylinder(0, 1.7 /* r */, fp);
2122
2123 Anim->rotation(h, nb_frames, round, fp);
2124 Anim->union_end(
2125 h, nb_frames, round,
2126 clipping_radius,
2127 fp);
2128
2129}
2130
2131
2132
2133
2134}}}
2135
2136
functions related to strings and character arrays
void replace_extension_with(char *p, const char *new_ext)
description of a function in reverse polish notation from the command line
Definition: globals.h:61
a set of functions in reverse polish notation
Definition: globals.h:87
std::vector< std::string > Variables
Definition: globals.h:92
void init(function_polish_description *Descr, int verbose_level)
various functions related to geometries
Definition: geometry.h:721
a data structure to store layered graphs or Hasse diagrams
Definition: graph_theory.h:654
void draw_with_options(std::string &fname, graphics::layered_graph_draw_options *O, int verbose_level)
void find_all_paths_between(int layer1, int node1, int layer2, int node2, std::vector< std::vector< int > > &All_Paths, int verbose_level)
void remove_edges(int layer1, int node1, int layer2, int node2, std::vector< std::vector< int > > &All_Paths, int verbose_level)
void scale_x_coordinates(double x_stretch, int verbose_level)
void create_spanning_tree(int f_place_x, int verbose_level)
void place_with_y_stretch(double y_stretch, int verbose_level)
void read_file(std::string &fname, int verbose_level)
creates 3D animations using Povray
Definition: graphics.h:29
void union_end(int h, int nb_frames, int round, double clipping_radius, std::ostream &fp)
Definition: animate.cpp:3018
void init(povray_job_description *Povray_job_description, void *extra_data, int verbose_level)
Definition: animate.cpp:42
void(* draw_frame_callback)(animate *A, int frame, int nb_frames_this_round, int round, double clipping, std::ostream &fp, int verbose_level)
Definition: graphics.h:38
void animate_one_round(int round, int verbose_level)
Definition: animate.cpp:72
void rotation(int h, int nb_frames, int round, std::ostream &fp)
Definition: animate.cpp:2986
a set of objects that should be drawn with certain povray properties
Definition: graphics.h:349
void draw(animate *Anim, std::ostream &ost, int f_group_is_animated, int frame, int verbose_level)
void animate_povray(povray_job_description *Povray_job_description, int verbose_level)
void draw_layered_graph_from_file(std::string &fname, layered_graph_draw_options *Opt, int verbose_level)
void draw_bitmap(draw_bitmap_control *C, int verbose_level)
void do_create_points_on_parabola(double desired_distance, int N, double a, double b, double c, int verbose_level)
void draw_projective(mp_graphics &G, int number, int animate_step, int animate_nb_of_steps, int f_transition, int transition_step, int transition_nb_steps, int f_title_page, int title_page_step, int f_trailer_page, int trailer_page_step)
void do_create_points_on_quartic(double desired_distance, int verbose_level)
void do_smooth_curve(std::string &curve_label, double desired_distance, int N, double t_min, double t_max, double boundary, function_polish_description *FP_descr, int verbose_level)
void draw_projective_curve(draw_projective_curve_description *Descr, layered_graph_draw_options *Opt, int verbose_level)
void tree_draw(tree_draw_options *Tree_draw_options, int verbose_level)
options for drawing an object of type layered_graph
Definition: graphics.h:457
a general 2D graphical output interface (metapost, tikz, postscript)
Definition: graphics.h:545
void plot_curve(int N, int *f_DNE, double *Dx, double *Dy, double dx, double dy)
void init(std::string &file_name, layered_graph_draw_options *Draw_options, int verbose_level)
Definition: mp_graphics.cpp:71
void aligned_text_array(int *Px, int *Py, int idx, const char *alignment, const char *p)
void polygon5(int *Px, int *Py, int i1, int i2, int i3, int i4, int i5)
void finish(std::ostream &ost, int verbose_level)
a continuous curve sampled by individual points
Definition: graphics.h:939
void init(int nb_dimensions, double desired_distance, double t0, double t1, int(*compute_point_function)(double t, double *pt, void *extra_data, int verbose_level), void *extra_data, double boundary, int N, int verbose_level)
std::vector< parametric_curve_point > Pts
Definition: graphics.h:950
std::vector< drawable_set_of_objects > Drawables
Definition: graphics.h:1221
void place_on_circle(int xmax, int ymax, int max_depth)
Definition: tree_node.cpp:246
void draw(std::string &fname, graphics::tree_draw_options *Tree_draw_options, layered_graph_draw_options *Opt, int verbose_level)
Definition: tree.cpp:224
void init(graphics::tree_draw_options *Tree_draw_options, int xmax, int ymax, int verbose_level)
Definition: tree.cpp:39
numerical functions, mostly concerned with double
Definition: globals.h:129
double distance_euclidean(double *x, double *y, int len)
Definition: numerics.cpp:984
void project_to_disc(int f_projection_on, int f_transition, int step, int nb_steps, double rad, double height, double x, double y, double &xp, double &yp)
Definition: numerics.cpp:3231
void int_matrix_read_csv(std::string &fname, int *&M, int &m, int &n, int verbose_level)
Definition: file_io.cpp:1477
void double_matrix_write_csv(std::string &fname, double *M, int m, int n)
Definition: file_io.cpp:1405
void get_vector_from_label(std::string &label, int *&v, int &sz, int verbose_level)
#define Int_vec_scan(A, B, C)
Definition: foundations.h:716
#define FREE_int(p)
Definition: foundations.h:640
#define ONE_MILLION
Definition: foundations.h:226
#define NEW_OBJECT(type)
Definition: foundations.h:638
#define FREE_OBJECT(p)
Definition: foundations.h:651
#define NEW_int(n)
Definition: foundations.h:625
#define ABS(x)
Definition: foundations.h:220
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define M_PI
Definition: foundations.h:237
#define Int_vec_print(A, B, C)
Definition: foundations.h:685
orbiter_kernel_system::orbiter_session * Orbiter
global Orbiter session
the orbiter library for the classification of combinatorial objects