Orbiter 2022
Combinatorial Objects
scene.cpp
Go to the documentation of this file.
1// scene.cpp
2//
3// Anton Betten
4//
5// started: February 13, 2018
6
7
8
9
10#include "foundations.h"
11
12using namespace std;
13
14
15
16#define EPSILON 0.01
17
18namespace orbiter {
19namespace layer1_foundations {
20namespace graphics {
21
22
23
24static double Hilbert_Cohn_Vossen_Lines[] = {
25 0,1,0,-2,0,-1, // 0 a1
26 0,0,1,-1,-2,0, // 1 a2
27 1,0,0,0,-1,-2, // 2 a3
28 0,-1,0,2,0,-1, // 3 a4
29 0,0,-1,-1,2,0, // 4 a5
30 -1,0,0,0,1,-2, // 5 a6
31 0,-1,0,1,0,-2, // 6 b1
32 0,0,-1,-2,1,0, // 7 b2
33 -1,0,0,0,2,-1, // 8 b3
34 0,1,0,-1,0,-2, // 9 b4
35 0,0,1,-2,-1,0, // 10 b5
36 1,0,0,0,-2,-1, // 11 b6
37 4./5., 3./5., 0, 0., 1., 1., // 12, 0, c12
38 3./5., 0., 4./5., 1, 1., 0., // 13, 1, c13
39 0.,0.,1., 1.,0.,0., // 14, 2 c14 at infinity
40 -4./5., 3./5., 0., 0., -1., 1., // 15, 3 c15
41 -3./5., 0., -4./5., -1., 1., 0., // 16, 4 c16
42 -3./5., 4./5., 0., 1., 0., 1., // 17, 5 c23
43 -4./5., -3./5., 0., 0., -1., 1., // 18, 6 c24
44 0., 1., 0., 1., 0., 0., // 19, 7 c25 at infinity
45 3./5., -4./5., 0., -1., 0., 1., // 20, 8 c26
46 3./5., 0., -4./5., -1., 1., 0., // 21, 9 c34
47 -3./5., -4./5., 0., -1., 0., 1., // 22, 10 c35
48 0., 0., 1., 0., 1., 0., // 23, 11 c36 at infinity
49 4./5., -3./5., 0., 0., 1., 1., // 24, 12 c45
50 -3./5., 0., 4./5., 1., 1., 0., // 25, 13 c46
51 3./5., 4./5., 0., 1., 0., 1., // 26, 14 c56
52 };
53
54
55static double Hilbert_Cohn_Vossen_tritangent_planes[] = {
56 // tritangent planes in dual coordinates, computed using Maple:
57
58 -1, -2, 2, 2, // 0 = start of tritangent planes
59 -2, 1, -1, 1,
60 1, -1, -2, 1,
61 -2, 2, -1, 2,
62 0, -1, 0, 1,
63 0, 1, 0, 1,
64 1, -2, -2, 2,
65 2, 1, 1, 1,
66 -1, -1, 2, 1,
67 2, 2, 1, 2,
68 2, -1, -2, 2,
69 -1, -2, 1, 1,
70 2, -1, -1, 1,
71 1, 2, 2, 2,
72 0, 0, -1, 1,
73 0, 0, 1, 1,
74 -2, 1, -2, 2,
75 1, 2, 1, 1,
76 -2, -2, 1, 2,
77 1, 1, 2, 1,
78 -1, 2, -1, 1,
79 2, 1, 2, 2,
80 -1, 0, 0, 1,
81 1, 0, 0, 1,
82 -1, 2, -2, 2,
83 -2, -1, 1, 1,
84 -1, 1, -2, 1,
85 2, -2, -1, 2,
86 -2, -1, 2, 2,
87 1, -2, -1, 1,
88 -5, -5, 5, 7,
89 -5, 5, -5, 1,
90 -5, 0, 0, 4,
91 5, -5, -5, 1,
92 0, 0, -5, 4,
93 -5, 5, -5, 7,
94 0, -5, 0, 4,
95 0, 0, 0, 1,
96 0, 5, 0, 4,
97 5, -5, -5, 7,
98 5, 0, 0, 4,
99 5, 5, 5, 1,
100 -5, -5, 5, 1,
101 5, 5, 5, 7,
102 0, 0, 5, 4
103 // end of tritangent planes
104
105
106 };
107
109{
110 line_radius = 0.05;
111 nb_lines = 0;
112 Line_coords = NULL;
113 nb_edges = 0;
114 Edge_points = NULL;
115 nb_points = 0;
116 Point_coords = NULL;
117 nb_planes = 0;
118 Plane_coords = NULL;
119 nb_quadrics = 0;
120 Quadric_coords = NULL;
121 nb_cubics = 0;
122 Quartic_coords = NULL;
123 nb_quartics = 0;
124 Quintic_coords = NULL;
125 nb_quintics = 0;
126 Octic_coords = NULL;
127 nb_octics = 0;
128 Cubic_coords = NULL;
129 nb_faces = 0;
130 Nb_face_points = NULL;
131 Face_points = NULL;
132
133 extra_data = NULL;
134
136 affine_space_q = 0;
138
139 nb_groups = 0;
140 //null();
141}
142
144{
145 freeself();
146}
147
149{
150}
151
153{
154 if (Line_coords) {
155 delete [] Line_coords;
156 }
157 if (Edge_points) {
158 FREE_int(Edge_points);
159 }
160 if (Point_coords) {
161 delete [] Point_coords;
162 }
163 if (Plane_coords) {
164 delete [] Plane_coords;
165 }
166 if (Quadric_coords) {
167 delete [] Quadric_coords;
168 }
169 if (Cubic_coords) {
170 delete [] Cubic_coords;
171 }
172 if (Quartic_coords) {
173 delete [] Quartic_coords;
174 }
175 if (Quintic_coords) {
176 delete [] Quintic_coords;
177 }
178 if (Octic_coords) {
179 delete [] Octic_coords;
180 }
181 if (Nb_face_points) {
182 FREE_int(Nb_face_points);
183 }
184 if (Face_points) {
185 int i;
186 for (i = 0; i < nb_faces; i++) {
187 FREE_int(Face_points[i]);
188 }
189 FREE_pint(Face_points);
190 }
191 null();
192}
193
194double scene::label(int idx, std::string &txt)
195{
196 if (idx >= nb_points) {
197 cout << "scene::label idx >= nb_points, "
198 "idx=" << idx << " nb_points=" << nb_points << endl;
199 exit(1);
200 }
201
202 {
203 pair<int, string> P(idx, txt);
204 Labels.push_back(P);
205 }
206 return Labels.size() - 1;
207}
208
209double scene::point_coords(int idx, int j)
210{
211 if (idx >= nb_points) {
212 cout << "scene::point_coords idx >= nb_points, "
213 "idx=" << idx << " nb_points=" << nb_points << endl;
214 exit(1);
215 }
216 if (j >= 3) {
217 cout << "scene::point_coords j >= 3, "
218 "j=" << j << endl;
219 exit(1);
220 }
221 return Point_coords[idx * 3 + j];
222}
223
224double scene::line_coords(int idx, int j)
225{
226 if (idx >= nb_lines) {
227 cout << "scene::line_coords idx >= nb_lines, "
228 "idx=" << idx << " nb_lines=" << nb_lines << endl;
229 exit(1);
230 }
231 if (j >= 6) {
232 cout << "scene::line_coords j >= 6, "
233 "j=" << j << endl;
234 exit(1);
235 }
236 return Line_coords[idx * 6 + j];
237}
238
239double scene::plane_coords(int idx, int j)
240{
241 if (idx >= nb_planes) {
242 cout << "scene::plane_coords idx >= nb_planes, "
243 "idx=" << idx << " nb_planes=" << nb_planes << endl;
244 exit(1);
245 }
246 if (j >= 3) {
247 cout << "scene::plane_coords j >= 4, "
248 "j=" << j << endl;
249 exit(1);
250 }
251 return Plane_coords[idx * 4 + j];
252}
253
254double scene::cubic_coords(int idx, int j)
255{
256 if (idx >= nb_cubics) {
257 cout << "scene::cubic_coords idx >= nb_cubics, "
258 "idx=" << idx << " nb_cubics=" << nb_cubics << endl;
259 exit(1);
260 }
261 if (j >= 20) {
262 cout << "scene::cubic_coords j >= 20, "
263 "j=" << j << endl;
264 exit(1);
265 }
266 return Cubic_coords[idx * 20 + j];
267}
268
269double scene::quadric_coords(int idx, int j)
270{
271 if (idx >= nb_quadrics) {
272 cout << "scene::quadric_coords idx >= nb_quadrics, "
273 "idx=" << idx << " nb_quadrics=" << nb_quadrics << endl;
274 exit(1);
275 }
276 if (j >= 10) {
277 cout << "scene::quadric_coords j >= 10, "
278 "j=" << j << endl;
279 exit(1);
280 }
281 return Quadric_coords[idx * 10 + j];
282}
283
284int scene::edge_points(int idx, int j)
285{
286 if (idx >= nb_planes) {
287 cout << "scene::edge_points idx >= nb_edges, "
288 "idx=" << idx << " nb_edges=" << nb_edges << endl;
289 exit(1);
290 }
291 if (j >= 2) {
292 cout << "scene::edge_points j >= 2, "
293 "j=" << j << endl;
294 exit(1);
295 }
296 return Edge_points[idx * 2 + j];
297}
298
300{
301 int j;
302
303 for (j = 0; j < 3; j++) {
304 cout << Point_coords[idx * 3 + j] << "\t";
305 }
306 cout << endl;
307}
308
309double scene::point_distance_euclidean(int pt_idx, double *y)
310{
311 numerics Num;
312 double d;
313
314 d = Num.distance_euclidean(y, Point_coords + pt_idx * 3, 3);
315 return d;
316}
317
319{
320 numerics Num;
321 double d;
322
323 d = Num.distance_from_origin(Point_coords + pt_idx * 3, 3);
324 return d;
325}
326
327double scene::distance_euclidean_point_to_point(int pt1_idx, int pt2_idx)
328{
329 numerics Num;
330 double d;
331
332 d = Num.distance_euclidean(Point_coords + pt1_idx * 3, Point_coords + pt2_idx * 3, 3);
333 return d;
334}
335
336void scene::init(int verbose_level)
337{
338 int f_v = (verbose_level >= 1);
339
340 if (f_v) {
341 cout << "scene::init" << endl;
342 }
343 Line_coords = new double [SCENE_MAX_LINES * 6];
344 nb_lines = 0;
345 Edge_points = NEW_int(SCENE_MAX_EDGES * 2);
346 nb_edges = 0;
347 Point_coords = new double [SCENE_MAX_POINTS * 3];
348 nb_points = 0;
349 Plane_coords = new double [SCENE_MAX_PLANES * 4];
350 nb_planes = 0;
351 Quadric_coords = new double [SCENE_MAX_QUADRICS * 10];
352 nb_quadrics = 0;
353 Cubic_coords = new double [SCENE_MAX_CUBICS * 20];
354 nb_cubics = 0;
355 Quartic_coords = new double [SCENE_MAX_QUARTICS * 35];
356 nb_quartics = 0;
357 Quintic_coords = new double [SCENE_MAX_QUINTICS * 56];
358 nb_quintics = 0;
359 Octic_coords = new double [SCENE_MAX_OCTICS * 165];
360 nb_octics = 0;
361 Face_points = NEW_pint(SCENE_MAX_FACES);
362 Nb_face_points = NEW_int(SCENE_MAX_FACES);
363 nb_faces = 0;
364 if (f_v) {
365 cout << "scene::done" << endl;
366 }
367}
368
369scene *scene::transformed_copy(double *A4, double *A4_inv,
370 double rad, int verbose_level)
371{
372 int f_v = (verbose_level >= 1);
373 scene *S;
374
375 if (f_v) {
376 cout << "scene::transformed_copy" << endl;
377 }
378
379 S = NEW_OBJECT(scene);
380 S->init(verbose_level);
381
382 transform_lines(S, A4, A4_inv, rad, verbose_level);
383 copy_edges(S, A4, A4_inv, verbose_level);
384 transform_points(S, A4, A4_inv, verbose_level);
385 transform_planes(S, A4, A4_inv, verbose_level);
386 transform_quadrics(S, A4, A4_inv, verbose_level);
387 transform_cubics(S, A4, A4_inv, verbose_level);
388 //transform_quartics(S, A4, A4_inv, verbose_level);
389 //transform_quintics(S, A4, A4_inv, verbose_level);
390 copy_faces(S, A4, A4_inv, verbose_level);
391
392 if (f_v) {
393 cout << "scene::transformed_copy done" << endl;
394 }
395 return S;
396}
397
399{
400 int i;
401 numerics N;
402
403 cout << "scene:" << endl;
404 cout << "nb_lines=" << nb_lines << endl;
405 for (i = 0; i < nb_lines; i++) {
406 cout << i << " / " << nb_lines << " : ";
407 N.vec_print(Line_coords + i * 6 + 0, 3);
408 cout << ", ";
409 N.vec_print(Line_coords + i * 6 + 3, 3);
410 cout << endl;
411 }
412 cout << "nb_planes=" << nb_planes << endl;
413 for (i = 0; i < nb_planes; i++) {
414 cout << i << " / " << nb_planes << " : ";
415 N.vec_print(Plane_coords + i * 4, 4);
416 cout << endl;
417 }
418 cout << "nb_points=" << nb_points << endl;
419 for (i = 0; i < nb_points; i++) {
420 cout << i << " / " << nb_points << " : ";
421 N.vec_print(Point_coords + i * 3, 3);
422 cout << endl;
423 }
424 cout << "nb_cubics=" << nb_cubics << endl;
425 for (i = 0; i < nb_cubics; i++) {
426 cout << i << " / " << nb_cubics << " : ";
427 N.vec_print(Cubic_coords + i * 20, 20);
428 cout << endl;
429 }
430
431 int k;
432
433 cout << "nb_edges=" << nb_edges << endl;
434 for (k = 0; k < nb_edges; k++) {
435 cout << k << " / " << nb_edges << " : ";
436 Int_vec_print(cout, Edge_points + k * 2, 2);
437 cout << endl;
438 }
439}
440
442 double *A4, double *A4_inv,
443 double rad,
444 int verbose_level)
445{
446 int f_v = (verbose_level >= 1);
447 double x[4], y[4];
448 double xx[4], yy[4];
449 double xxx[4], yyy[4];
450 int i;
451 numerics N;
452
453
454 if (f_v) {
455 cout << "scene::transform_lines" << endl;
456 }
457
458 for (i = 0; i < nb_lines; i++) {
459 N.vec_copy(Line_coords + i * 6 + 0, x, 3);
460 x[3] = 1.;
461 N.vec_copy(Line_coords + i * 6 + 3, y, 3);
462 y[3] = 1.;
463 N.mult_matrix_4x4(x, A4, xx);
464 N.mult_matrix_4x4(y, A4, yy);
465 if (ABS(xx[3]) < 0.0001) {
466 cout << "scene::transform_lines warning, "
467 "point x is moved to infinity" << endl;
468 exit(1);
469 }
470 if (ABS(yy[3]) < 0.0001) {
471 cout << "scene::transform_lines warning, "
472 "point y is moved to infinity" << endl;
473 exit(1);
474 }
476 if (ABS(xx[3] - 1.) > 0.0001) {
477 cout << "scene::transform_lines warning, "
478 "point xx is not an affine point" << endl;
479 exit(1);
480 }
482 if (ABS(yy[3] - 1.) > 0.0001) {
483 cout << "scene::transform_lines warning, "
484 "point yy is not an affine point" << endl;
485 exit(1);
486 }
487 if (N.line_centered(xx, yy, xxx, yyy, 10., verbose_level - 1)) {
488 S->line(xxx[0], xxx[1], xxx[2], yyy[0], yyy[1], yyy[2]);
489 }
490 }
491
492 if (f_v) {
493 cout << "scene::transform_lines done" << endl;
494 }
495}
496
497void scene::copy_edges(scene *S, double *A4, double *A4_inv,
498 int verbose_level)
499{
500 int f_v = (verbose_level >= 1);
501 int a, b;
502 int i;
503
504
505 if (f_v) {
506 cout << "scene::copy_edges" << endl;
507 }
508
509 for (i = 0; i < nb_edges; i++) {
510 a = Edge_points[i * 2 + 0];
511 b = Edge_points[i * 2 + 1];
512 S->edge(a, b);
513 }
514 if (f_v) {
515 cout << "scene::copy_edges done" << endl;
516 }
517}
518
519void scene::transform_points(scene *S, double *A4, double *A4_inv,
520 int verbose_level)
521{
522 int f_v = (verbose_level >= 1);
523 double x[4];
524 double xx[4];
525 int i;
526 numerics N;
527
528
529 if (f_v) {
530 cout << "scene::transform_points" << endl;
531 }
532
533 for (i = 0; i < nb_points; i++) {
534 N.vec_copy(Point_coords + i * 3, x, 3);
535 x[3] = 1.;
536 N.mult_matrix_4x4(x, A4, xx);
537 if (ABS(xx[3]) < 0.0001) {
538 cout << "scene::transform_lines warning, "
539 "point x is moved to infinity" << endl;
540 exit(1);
541 }
543 if (ABS(xx[3] - 1.) > 0.0001) {
544 cout << "scene::transform_lines warning, "
545 "point xx is not an affine point" << endl;
546 exit(1);
547 }
548 S->point(xx[0], xx[1], xx[2]);
549 }
550
551 if (f_v) {
552 cout << "scene::transform_points done" << endl;
553 }
554}
555
556void scene::transform_planes(scene *S, double *A4, double *A4_inv,
557 int verbose_level)
558{
559 int f_v = (verbose_level >= 1);
560 double x[4];
561 double xx[4];
562 double Avt[16];
563 int i;
564 numerics N;
565
566
567 if (f_v) {
568 cout << "scene::transform_planes" << endl;
569 }
570
571 N.transpose_matrix_4x4(A4_inv, Avt);
572
573
574 for (i = 0; i < nb_planes; i++) {
575 N.vec_copy(Plane_coords + i * 4, x, 4);
576 x[3] *= -1.;
577
578 N.mult_matrix_4x4(x, Avt, xx);
579
580 xx[3] *= -1.;
581 S->plane(xx[0], xx[1], xx[2], xx[3]);
582 }
583
584 if (f_v) {
585 cout << "scene::transform_planes done" << endl;
586 }
587}
588
589void scene::transform_quadrics(scene *S, double *A4, double *A4_inv,
590 int verbose_level)
591{
592 int f_v = (verbose_level >= 1);
593 double coeff_in[10];
594 double coeff_out[10];
595 int i;
596 numerics N;
597
598
599 if (f_v) {
600 cout << "scene::transform_quadrics" << endl;
601 }
602
603
604 for (i = 0; i < nb_quadrics; i++) {
605 N.vec_copy(Quadric_coords + i * 10, coeff_in, 10);
606
607 N.substitute_quadric_linear(coeff_in, coeff_out,
608 A4_inv, verbose_level);
609
610 S->quadric(coeff_out);
611 }
612
613 if (f_v) {
614 cout << "scene::transform_quadrics done" << endl;
615 }
616}
617
618void scene::transform_cubics(scene *S, double *A4, double *A4_inv,
619 int verbose_level)
620{
621 int f_v = (verbose_level >= 1);
622 double coeff_in[20];
623 double coeff_out[20];
624 int i;
625 numerics N;
626
627
628 if (f_v) {
629 cout << "scene::transform_cubics" << endl;
630 }
631
632
633 for (i = 0; i < nb_cubics; i++) {
634 N.vec_copy(Cubic_coords + i * 20, coeff_in, 20);
635
637 A4_inv, verbose_level);
638
639 S->cubic(coeff_out);
640 }
641
642 if (f_v) {
643 cout << "scene::transform_cubics done" << endl;
644 }
645}
646
647void scene::transform_quartics(scene *S, double *A4, double *A4_inv,
648 int verbose_level)
649{
650 int f_v = (verbose_level >= 1);
651
652
653 if (f_v) {
654 cout << "scene::transform_quartics" << endl;
655 }
656
657 cout << "scene::transform_quartics not yet implemented" << endl;
658
659 double coeff_in[35];
660 double coeff_out[35];
661 int i;
662 numerics N;
663
664
665 for (i = 0; i < nb_quartics; i++) {
666 N.vec_copy(Quartic_coords + i * 35, coeff_in, 35);
667
669 A4_inv, verbose_level);
670
671 S->quartic(coeff_out);
672 }
673
674 if (f_v) {
675 cout << "scene::transform_quartics done" << endl;
676 }
677}
678
679void scene::transform_quintics(scene *S, double *A4, double *A4_inv,
680 int verbose_level)
681{
682 int f_v = (verbose_level >= 1);
683
684
685 if (f_v) {
686 cout << "scene::transform_quartics" << endl;
687 }
688
689 cout << "scene::transform_quintics not yet implemented" << endl;
690
691 double coeff_in[56];
692 double coeff_out[56];
693 int i;
694 numerics N;
695
696
697 for (i = 0; i < nb_quintics; i++) {
698 N.vec_copy(Quintic_coords + i * 56, coeff_in, 56);
699
701 A4_inv, verbose_level);
702
703 S->quintic(coeff_out);
704 }
705
706 if (f_v) {
707 cout << "scene::transform_quintics done" << endl;
708 }
709}
710
711void scene::copy_faces(scene *S, double *A4, double *A4_inv,
712 int verbose_level)
713{
714 int f_v = (verbose_level >= 1);
715 int nb_pts, *pts;
716 int i;
717
718
719 if (f_v) {
720 cout << "scene::copy_faces" << endl;
721 }
722
723 for (i = 0; i < nb_faces; i++) {
724 pts = Face_points[i];
725 nb_pts = Nb_face_points[i];
726 S->face(pts, nb_pts);
727 }
728 if (f_v) {
729 cout << "scene::copy_faces done" << endl;
730 }
731}
732
733
734int scene::line_pt_and_dir(double *x6, double rad, int verbose_level)
735{
736 int f_v = (verbose_level >= 1);
737 double pt[6];
738 double pt2[6];
739 numerics N;
740 int ret;
741
742 if (f_v) {
743 cout << "scene::line_pt_and_dir" << endl;
744 }
745 pt[0] = x6[0];
746 pt[1] = x6[1];
747 pt[2] = x6[2];
748 pt[3] = x6[0] + x6[3];
749 pt[4] = x6[1] + x6[4];
750 pt[5] = x6[2] + x6[5];
751 if (N.line_centered_tolerant(pt, pt + 3,
752 pt2, pt2 + 3,
753 rad, verbose_level)) {
754 Line_coords[nb_lines * 6 + 0] = pt2[0];
755 Line_coords[nb_lines * 6 + 1] = pt2[1];
756 Line_coords[nb_lines * 6 + 2] = pt2[2];
757 Line_coords[nb_lines * 6 + 3] = pt2[3];
758 Line_coords[nb_lines * 6 + 4] = pt2[4];
759 Line_coords[nb_lines * 6 + 5] = pt2[5];
760 nb_lines++;
761 if (nb_lines >= SCENE_MAX_LINES) {
762 cout << "too many lines" << endl;
763 exit(1);
764 }
765 ret = TRUE;
766 }
767 else {
768 ret = FALSE;
769 }
770 if (f_v) {
771 cout << "scene::line_pt_and_dir done" << endl;
772 }
773 return ret;
774}
775
776int scene::line_pt_and_dir_and_copy_points(double *x6, double rad, int verbose_level)
777{
778 int f_v = (verbose_level >= 1);
779 double pt[6];
780 double pt2[6];
781 numerics N;
782 int ret;
783
784 if (f_v) {
785 cout << "scene::line_pt_and_dir_and_copy_points" << endl;
786 }
787 pt[0] = x6[0];
788 pt[1] = x6[1];
789 pt[2] = x6[2];
790 pt[3] = x6[0] + x6[3];
791 pt[4] = x6[1] + x6[4];
792 pt[5] = x6[2] + x6[5];
793 if (N.line_centered_tolerant(pt, pt + 3,
794 pt2, pt2 + 3,
795 rad, verbose_level)) {
796 Line_coords[nb_lines * 6 + 0] = pt2[0];
797 Line_coords[nb_lines * 6 + 1] = pt2[1];
798 Line_coords[nb_lines * 6 + 2] = pt2[2];
799 Line_coords[nb_lines * 6 + 3] = pt2[3];
800 Line_coords[nb_lines * 6 + 4] = pt2[4];
801 Line_coords[nb_lines * 6 + 5] = pt2[5];
802 nb_lines++;
803 if (nb_lines >= SCENE_MAX_LINES) {
804 cout << "too many lines" << endl;
805 exit(1);
806 }
807 points(pt2, 2);
808 ret = TRUE;
809 }
810 else {
811 cout << "line_pt_and_dir_and_copy_points could not create points" << endl;
812 exit(1);
813 }
814 if (f_v) {
815 cout << "scene::line_pt_and_dir_and_copy_points done" << endl;
816 }
817 return ret;
818}
819
820
821int scene::line_through_two_pts(double *x6, double rad)
822{
823 double pt[6];
824 double pt2[6];
825 numerics N;
826 int verbose_level = 0;
827
828 pt[0] = x6[0];
829 pt[1] = x6[1];
830 pt[2] = x6[2];
831 pt[3] = x6[3];
832 pt[4] = x6[4];
833 pt[5] = x6[5];
834 if (N.line_centered(pt, pt + 3,
835 pt2, pt2 + 3,
836 rad, verbose_level)) {
837 Line_coords[nb_lines * 6 + 0] = pt2[0];
838 Line_coords[nb_lines * 6 + 1] = pt2[1];
839 Line_coords[nb_lines * 6 + 2] = pt2[2];
840 Line_coords[nb_lines * 6 + 3] = pt2[3];
841 Line_coords[nb_lines * 6 + 4] = pt2[4];
842 Line_coords[nb_lines * 6 + 5] = pt2[5];
843 nb_lines++;
844 if (nb_lines >= SCENE_MAX_LINES) {
845 cout << "too many lines" << endl;
846 exit(1);
847 }
848 return nb_lines - 1;
849 }
850 else {
851 return -1;
852 }
853}
854
855int scene::line6(double *x6)
856{
857 Line_coords[nb_lines * 6 + 0] = x6[0];
858 Line_coords[nb_lines * 6 + 1] = x6[1];
859 Line_coords[nb_lines * 6 + 2] = x6[2];
860 Line_coords[nb_lines * 6 + 3] = x6[3];
861 Line_coords[nb_lines * 6 + 4] = x6[4];
862 Line_coords[nb_lines * 6 + 5] = x6[5];
863 nb_lines++;
864 if (nb_lines >= SCENE_MAX_LINES) {
865 cout << "too many lines" << endl;
866 exit(1);
867 }
868 return nb_lines - 1;
869}
870
871int scene::line(double x1, double x2, double x3,
872 double y1, double y2, double y3)
873{
874 Line_coords[nb_lines * 6 + 0] = x1;
875 Line_coords[nb_lines * 6 + 1] = x2;
876 Line_coords[nb_lines * 6 + 2] = x3;
877 Line_coords[nb_lines * 6 + 3] = y1;
878 Line_coords[nb_lines * 6 + 4] = y2;
879 Line_coords[nb_lines * 6 + 5] = y3;
880 nb_lines++;
881 if (nb_lines >= SCENE_MAX_LINES) {
882 cout << "too many lines" << endl;
883 exit(1);
884 }
885 return nb_lines - 1;
886}
887
888int scene::line_after_recentering(double x1, double x2, double x3,
889 double y1, double y2, double y3, double rad)
890{
891 double x[3], y[3];
892 double xx[3], yy[3];
893 numerics N;
894 int verbose_level = 0;
895
896 x[0] = x1;
897 x[1] = x2;
898 x[2] = x3;
899 y[0] = y1;
900 y[1] = y2;
901 y[2] = y3;
902
903 N.line_centered(x, y, xx, yy, rad, verbose_level);
904
905 Line_coords[nb_lines * 6 + 0] = xx[0];
906 Line_coords[nb_lines * 6 + 1] = xx[1];
907 Line_coords[nb_lines * 6 + 2] = xx[2];
908 Line_coords[nb_lines * 6 + 3] = yy[0];
909 Line_coords[nb_lines * 6 + 4] = yy[1];
910 Line_coords[nb_lines * 6 + 5] = yy[2];
911 points(Line_coords + nb_lines * 6, 2 /* nb_points */);
912 nb_lines++;
913 if (nb_lines >= SCENE_MAX_LINES) {
914 cout << "too many lines" << endl;
915 exit(1);
916 }
917 return nb_lines - 1;
918}
919
920int scene::line_through_two_points(int pt1, int pt2, double rad)
921{
922 double x[3], y[3];
923 double xx[3], yy[3];
924 numerics N;
925 int verbose_level = 0;
926
927 N.vec_copy(Point_coords + pt1 * 3, x, 3);
928 N.vec_copy(Point_coords + pt2 * 3, y, 3);
929
930 N.line_centered(x, y, xx, yy, 10., verbose_level);
931
932 Line_coords[nb_lines * 6 + 0] = xx[0];
933 Line_coords[nb_lines * 6 + 1] = xx[1];
934 Line_coords[nb_lines * 6 + 2] = xx[2];
935 Line_coords[nb_lines * 6 + 3] = yy[0];
936 Line_coords[nb_lines * 6 + 4] = yy[1];
937 Line_coords[nb_lines * 6 + 5] = yy[2];
938 nb_lines++;
939 if (nb_lines >= SCENE_MAX_LINES) {
940 cout << "too many lines" << endl;
941 exit(1);
942 }
943 return nb_lines - 1;
944}
945
946int scene::edge(int pt1, int pt2)
947{
948 Edge_points[nb_edges * 2 + 0] = pt1;
949 Edge_points[nb_edges * 2 + 1] = pt2;
950 nb_edges++;
951 if (nb_edges >= SCENE_MAX_EDGES) {
952 cout << "too many edges" << endl;
953 exit(1);
954 }
955 return nb_edges - 1;
956}
957
958void scene::points(double *Coords, int nb_points)
959{
960 int i;
961
962 for (i = 0; i < nb_points; i++) {
963 point(Coords[i * 3 + 0], Coords[i * 3 + 1], Coords[i * 3 + 2]);
964 }
965}
966
967int scene::point(double x1, double x2, double x3)
968{
969 Point_coords[nb_points * 3 + 0] = x1;
970 Point_coords[nb_points * 3 + 1] = x2;
971 Point_coords[nb_points * 3 + 2] = x3;
972 nb_points++;
974 cout << "too many points" << endl;
975 exit(1);
976 }
977 return nb_points - 1;
978}
979
981{
982 return point_center_of_mass(Face_points[face_idx], Nb_face_points[face_idx]);
983}
984
986{
987 return point_center_of_mass(Edge_points + edge_idx * 2, 2);
988}
989
990int scene::point_center_of_mass(int *Pt_idx, int nb_pts)
991{
992 double x[3];
993 numerics N;
994
995 N.center_of_mass(Point_coords, 3 /* len */, Pt_idx, nb_pts, x);
996 return point(x[0], x[1], x[2]);
997}
998
999int scene::triangle(int line1, int line2, int line3, int verbose_level)
1000{
1001 int f_v = (verbose_level >= 1);
1002 int pt[3], idx;
1003
1004 if (f_v) {
1005 cout << "scene::triangle" << endl;
1006 }
1007 pt[0] = point_as_intersection_of_two_lines(line1, line2);
1008 pt[1] = point_as_intersection_of_two_lines(line2, line3);
1009 pt[2] = point_as_intersection_of_two_lines(line3, line1);
1010 idx = face3(pt[0], pt[1], pt[2]);
1011 if (f_v) {
1012 cout << "scene::triangle done" << endl;
1013 }
1014 return idx;
1015}
1016
1018{
1019 double x[3], y[3], z[3], u[3], v[3];
1020 double System[9];
1021 int ker, idx, i;
1022 //int base_cols[3];
1023 double lambda;
1024 double Ker[9];
1025 numerics N;
1026
1027 N.vec_copy(Line_coords + line1 * 6, x, 3);
1028 N.vec_copy(Line_coords + line2 * 6, y, 3);
1029 N.vec_subtract(Line_coords + line1 * 6 + 3, Line_coords + line1 * 6, u, 3);
1030 N.vec_subtract(Line_coords + line2 * 6 + 3, Line_coords + line2 * 6, v, 3);
1031
1032 // we need to solve
1033 // x + lambda * u = y + mu * v
1034 // so
1035 // lambda * u + mu * (- v) = y - x
1036
1037 for (i = 0; i < 3; i++) {
1038 System[i * 3 + 0] = u[i];
1039 System[i * 3 + 1] = -1. * v[i];
1040 System[i * 3 + 2] = y[i] - x[i];
1041 }
1042 // rk = Gauss_elimination(System, 3, 3,
1043 //base_cols, TRUE /* f_complete */, 0 /* verbose_level */);
1044 ker = N.Null_space(System, 3, 3, Ker, 0 /* verbose_level */);
1045 if (ker != 1) {
1046 cout << "scene::point_as_intersection_of_two_lines ker != 1" << endl;
1047 exit(1);
1048 }
1049 N.vec_normalize_from_back(Ker, 3);
1051 lambda = Ker[0];
1052 for (i = 0; i < 3; i++) {
1053 z[i] = x[i] + lambda * u[i];
1054 }
1055 idx = point(z[0], z[1], z[2]);
1056 return idx;
1057}
1058
1060{
1061 double y[4];
1062 double d, dv;
1063 d = sqrt(x4[0] * x4[0] + x4[1] * x4[1] + x4[2] * x4[2]);
1064 dv = 1. / d;
1065 y[0] = x4[0] * dv;
1066 y[1] = x4[1] * dv;
1067 y[2] = x4[2] * dv;
1068 y[3] = - x4[3] * dv;
1069 return plane(y[0], y[1], y[2], y[3]);
1070}
1071
1072
1073int scene::plane(double x1, double x2, double x3, double a)
1074// A plane is called a polynomial shape because
1075// it is defined by a first order polynomial equation.
1076// Given a plane: plane { <A, B, C>, D }
1077// it can be represented by the equation
1078// A*x + B*y + C*z - D*sqrt(A^2 + B^2 + C^2) = 0.
1079// see http://www.povray.org/documentation/view/3.6.1/297/
1080// Example:
1081// plane { <0, 1, 0>, 4 }
1082// This is a plane where straight up is defined in the positive y-direction.
1083// The plane is 4 units in that direction away from the origin.
1084// Because most planes are defined with surface normals in the direction
1085// of an axis you will often see planes defined using the x, y or z
1086// built-in vector identifiers. The example above could be specified as:
1087// plane { y, 4 }
1088
1089
1090//intersection {
1091// box { <-1.5, -1, -1>, <0.5, 1, 1> }
1092// cylinder { <0.5, 0, -1>, <0.5, 0, 1>, 1 }
1093// }
1094{
1095 Plane_coords[nb_planes * 4 + 0] = x1;
1096 Plane_coords[nb_planes * 4 + 1] = x2;
1097 Plane_coords[nb_planes * 4 + 2] = x3;
1098 Plane_coords[nb_planes * 4 + 3] = a;
1099 nb_planes++;
1100 if (nb_planes >= SCENE_MAX_PLANES) {
1101 cout << "too many planes" << endl;
1102 exit(1);
1103 }
1104 return nb_planes - 1;
1105}
1106
1107int scene::plane_through_three_points(int pt1, int pt2, int pt3)
1108{
1109 double p1[3], p2[3], p3[3], n[3], d;
1110 numerics N;
1111
1112 N.vec_copy(Point_coords + pt1 * 3, p1, 3);
1113 N.vec_copy(Point_coords + pt2 * 3, p2, 3);
1114 N.vec_copy(Point_coords + pt3 * 3, p3, 3);
1115
1116#if 0
1117 cout << "p1=" << endl;
1118 print_system(p1, 1, 3);
1119 cout << endl;
1120 cout << "p2=" << endl;
1121 print_system(p2, 1, 3);
1122 cout << endl;
1123 cout << "p3=" << endl;
1124 print_system(p3, 1, 3);
1125 cout << endl;
1126#endif
1127
1128 N.plane_through_three_points(p1, p2, p3, n, d);
1129 return plane(n[0], n[1], n[2], d);
1130}
1131
1133 int line_idx1, int line_idx2, int line_idx3,
1134 int verbose_level)
1135{
1136 int f_v = (verbose_level >= 1);
1137 double coeff[10];
1138 double points[9 * 3];
1139 double System[9 * 10];
1140 double v[3];
1141 double x, y, z;
1142 int idx;
1143 int i, k;
1144 numerics N;
1145
1146 if (f_v) {
1147 cout << "scene::quadric_through_three_lines" << endl;
1148 }
1149 N.vec_copy(Line_coords + line_idx1 * 6, points + 0, 3);
1150 N.vec_copy(Line_coords + line_idx1 * 6 + 3, points + 3, 3);
1151 N.vec_subtract(points + 3, points + 0, v, 3);
1152 N.vec_scalar_multiple(v, 2., 3);
1153 N.vec_add(points + 0, v, points + 6, 3);
1154
1155 N.vec_copy(Line_coords + line_idx2 * 6, points + 9, 3);
1156 N.vec_copy(Line_coords + line_idx2 * 6 + 3, points + 12, 3);
1157 N.vec_subtract(points + 12, points + 9, v, 3);
1158 N.vec_scalar_multiple(v, 2., 3);
1159 N.vec_add(points + 9, v, points + 15, 3);
1160
1161 N.vec_copy(Line_coords + line_idx3 * 6, points + 18, 3);
1162 N.vec_copy(Line_coords + line_idx3 * 6 + 3, points + 21, 3);
1163 N.vec_subtract(points + 21, points + 18, v, 3);
1164 N.vec_scalar_multiple(v, 2., 3);
1165 N.vec_add(points + 18, v, points + 24, 3);
1166
1167
1168 for (i = 0; i < 9; i++) {
1169 x = points[i * 3 + 0];
1170 y = points[i * 3 + 1];
1171 z = points[i * 3 + 2];
1172 System[i * 10 + 0] = x * x;
1173 System[i * 10 + 1] = x * y;
1174 System[i * 10 + 2] = x * z;
1175 System[i * 10 + 3] = x;
1176 System[i * 10 + 4] = y * y;
1177 System[i * 10 + 5] = y * z;
1178 System[i * 10 + 6] = y;
1179 System[i * 10 + 7] = z * z;
1180 System[i * 10 + 8] = z;
1181 System[i * 10 + 9] = 1;
1182 }
1183
1184 k = N.Null_space(System, 9, 10, coeff, 0 /* verbose_level */);
1185 if (k != 1) {
1186 cout << "scene::quadric_through_three_lines k != 1" << endl;
1187 exit(1);
1188 }
1189
1190
1191 idx = quadric(coeff);
1192 if (f_v) {
1193 cout << "scene::quadric_through_three_lines done" << endl;
1194 }
1195 return idx;
1196}
1197
1198int scene::quintic(double *coeff_56)
1199// povray (lexicographic) ordering of monomials:
1200// http://www.povray.org/documentation/view/3.6.1/298/
1201{
1202 int i;
1203
1205 cout << "too many quintics" << endl;
1206 exit(1);
1207 }
1208 for (i = 0; i < 56; i++) {
1209 Quintic_coords[nb_quintics * 56 + i] = coeff_56[i];
1210 }
1211 nb_quintics++;
1212 return nb_quintics - 1;
1213
1214}
1215
1216
1217int scene::octic(double *coeff_165)
1218{
1219 int i;
1220
1221 if (nb_octics >= SCENE_MAX_OCTICS) {
1222 cout << "too many octics" << endl;
1223 exit(1);
1224 }
1225 for (i = 0; i < 165; i++) {
1226 Octic_coords[nb_octics * 165 + i] = coeff_165[i];
1227 }
1228 nb_octics++;
1229 return nb_octics - 1;
1230
1231}
1232
1233int scene::quadric(double *coeff)
1234// povray (lexicographic) ordering of monomials:
1235// http://www.povray.org/documentation/view/3.6.1/298/
1236// 1: x^2
1237// 2: xy
1238// 3: xz
1239// 4: x
1240// 5: y^2
1241// 6: yz
1242// 7: y
1243// 8: z^2
1244// 9: z
1245// 10: 1
1246{
1247 int i;
1248
1250 cout << "too many quadrics" << endl;
1251 exit(1);
1252 }
1253 for (i = 0; i < 10; i++) {
1254 Quadric_coords[nb_quadrics * 10 + i] = coeff[i];
1255 }
1256 nb_quadrics++;
1257 return nb_quadrics - 1;
1258}
1259
1260
1262{
1263 double eqn[20];
1264
1265 eqn[0] = coeff[0];
1266 eqn[1] = coeff[4];
1267 eqn[2] = coeff[5];
1268 eqn[3] = coeff[6];
1269 eqn[4] = coeff[7];
1270 eqn[5] = coeff[16];
1271 eqn[6] = coeff[17];
1272 eqn[7] = coeff[10];
1273 eqn[8] = coeff[18];
1274 eqn[9] = coeff[13];
1275 eqn[10] = coeff[1];
1276 eqn[11] = coeff[8];
1277 eqn[12] = coeff[9];
1278 eqn[13] = coeff[11];
1279 eqn[14] = coeff[19];
1280 eqn[15] = coeff[14];
1281 eqn[16] = coeff[2];
1282 eqn[17] = coeff[12];
1283 eqn[18] = coeff[15];
1284 eqn[19] = coeff[3];
1285 return cubic(eqn);
1286}
1287
1288int scene::cubic(double *coeff)
1289// povray (lexicographic) ordering of monomials:
1290// http://www.povray.org/documentation/view/3.6.1/298/
1291// 0: x^3
1292// 1: x^2y
1293// 2: x^2z
1294// 3: x^2
1295// 4: xy^2
1296// 5: xyz
1297// 6: xy
1298// 7: xz^2
1299// 8: xz
1300// 9: x
1301// 10: y^3
1302// 11: y^2z
1303// 12: y^2
1304// 13: yz^2
1305// 14: yz
1306// 15: y
1307// 16: z^3
1308// 17: z^2
1309// 18: z
1310// 19: 1
1311{
1312 int i;
1313
1314 for (i = 0; i < 20; i++) {
1315 Cubic_coords[nb_cubics * 20 + i] = coeff[i];
1316 }
1317 nb_cubics++;
1318 if (nb_cubics >= SCENE_MAX_CUBICS) {
1319 cout << "too many cubics" << endl;
1320 exit(1);
1321 }
1322 return nb_cubics - 1;
1323}
1324
1326 double angle_start, double angle_max, double angle_min,
1327 double *coeff1, double *coeff2,
1328 int verbose_level)
1329{
1330 int f_v = (verbose_level >= 1);
1331
1332 if (f_v) {
1333 cout << "scene::deformation_of_cubic_lex" << endl;
1334 }
1335 double phi_step, phi, s1, s2, c, theta, t, mu, lambda;
1336 double coeff3[20];
1337 int h, nb_frames_half, i;
1338
1339 nb_frames_half = nb_frames >> 1;
1340 phi_step = 2 * 2 * M_PI / (nb_frames - 1);
1341 s1 = (angle_max - angle_start) / 2.;
1342 s2 = (angle_start - angle_min) / 2.;
1343
1344 for (h = 0; h < nb_frames; h++) {
1345 phi = h * phi_step;
1346 c = 1. - cos(phi);
1347 if (h < nb_frames_half) {
1348 theta = angle_start + c * s1;
1349 }
1350 else {
1351 theta = angle_start - c * s2;
1352 }
1353 t = tan(theta);
1354 if (isnan(t) || ABS(t) > 1000000.) {
1355 mu = 0;
1356 lambda = 1;
1357 }
1358 else if (t > 1.) {
1359 mu = 1. / t;
1360 lambda = 1;
1361 }
1362 else {
1363 mu = 1;
1364 lambda = t;
1365 }
1366 for (i = 0; i < 20; i++) {
1367 coeff3[i] = mu * coeff1[i] + lambda * coeff2[i];
1368 }
1369 cubic(coeff3);
1370 }
1371 if (f_v) {
1372 cout << "scene::deformation_of_cubic_lex done" << endl;
1373 }
1374}
1375
1376int scene::cubic_Goursat_ABC(double A, double B, double C)
1377{
1378 double coeffs[20];
1379 int i;
1380
1381 for (i = 0; i < 20; i++) {
1382 coeffs[i] = 0;
1383 }
1384 coeffs[5] = A; // xyz
1385 coeffs[3] = B; // x^2
1386 coeffs[12] = B; // y^2
1387 coeffs[17] = B; // z^2
1388 coeffs[19] = C; // 1
1389 return cubic(coeffs);
1390}
1391
1392int scene::quartic(double *coeff)
1393// povray (lexicographic) ordering of monomials:
1394// http://www.povray.org/documentation/view/3.6.1/298/
1395{
1396 int i;
1397
1399 cout << "too many quartics" << endl;
1400 exit(1);
1401 }
1402 for (i = 0; i < 35; i++) {
1403 Quartic_coords[nb_quartics * 35 + i] = coeff[i];
1404 }
1405 nb_quartics++;
1406 return nb_quartics - 1;
1407}
1408
1409int scene::face(int *pts, int nb_pts)
1410{
1411 Face_points[nb_faces] = NEW_int(nb_pts);
1412 Nb_face_points[nb_faces] = nb_pts;
1413 Int_vec_copy(pts, Face_points[nb_faces], nb_pts);
1414 nb_faces++;
1415 if (nb_faces >= SCENE_MAX_FACES) {
1416 cout << "too many faces" << endl;
1417 exit(1);
1418 }
1419 return nb_faces - 1;
1420}
1421
1422int scene::face3(int pt1, int pt2, int pt3)
1423{
1424 int pts[3];
1425
1426 pts[0] = pt1;
1427 pts[1] = pt2;
1428 pts[2] = pt3;
1429 return face(pts, 3);
1430}
1431
1432int scene::face4(int pt1, int pt2, int pt3, int pt4)
1433{
1434 int pts[4];
1435
1436 pts[0] = pt1;
1437 pts[1] = pt2;
1438 pts[2] = pt3;
1439 pts[3] = pt4;
1440 return face(pts, 4);
1441}
1442
1443int scene::face5(int pt1, int pt2, int pt3, int pt4, int pt5)
1444{
1445 int pts[5];
1446
1447 pts[0] = pt1;
1448 pts[1] = pt2;
1449 pts[2] = pt3;
1450 pts[3] = pt4;
1451 pts[4] = pt5;
1452 return face(pts, 5);
1453}
1454
1455
1456
1457void scene::draw_lines_with_selection(int *selection, int nb_select,
1458 std::string &options, ostream &ost)
1459{
1460 int i, j, h, s;
1461 numerics N;
1462
1463 ost << endl;
1464 ost << " union{ // lines" << endl;
1465 ost << endl;
1466 ost << " #declare r=" << line_radius << "; " << endl;
1467 //ost << " #declare b=4;" << endl;
1468 ost << endl;
1469 for (i = 0; i < nb_select; i++) {
1470 s = selection[i];
1471 j = s;
1472 ost << " cylinder{<";
1473 for (h = 0; h < 3; h++) {
1474 N.output_double(Line_coords[j * 6 + h], ost);
1475 if (h < 2) {
1476 ost << ", ";
1477 }
1478 }
1479 ost << ">,<";
1480 for (h = 0; h < 3; h++) {
1481 N.output_double(Line_coords[j * 6 + 3 + h], ost);
1482 if (h < 2) {
1483 ost << ", ";
1484 }
1485 }
1486 ost << ">, r } // line " << j << endl;
1487 }
1488 ost << endl;
1489 ost << " " << options << "" << endl;
1490 //ost << " pigment{" << color << "}" << endl;
1491 ost << " }" << endl;
1492}
1493
1495 std::string &options, ostream &ost)
1496{
1497 int j, h, s;
1498 numerics N;
1499
1500 ost << endl;
1501 ost << " union{ // lines" << endl;
1502 ost << endl;
1503 ost << " #declare r=" << line_radius << "; " << endl;
1504 //ost << " #declare b=4;" << endl;
1505 ost << endl;
1506 s = line_idx;
1507 j = s;
1508 ost << " cylinder{<";
1509 for (h = 0; h < 3; h++) {
1510 N.output_double(Line_coords[j * 6 + h], ost);
1511 if (h < 2) {
1512 ost << ", ";
1513 }
1514 }
1515 ost << ">,<";
1516 for (h = 0; h < 3; h++) {
1517 N.output_double(Line_coords[j * 6 + 3 + h], ost);
1518 if (h < 2) {
1519 ost << ", ";
1520 }
1521 }
1522 ost << ">, r } // line " << j << endl;
1523 ost << endl;
1524 ost << " " << options << "" << endl;
1525 //ost << " pigment{" << color << "}" << endl;
1526 ost << " }" << endl;
1527}
1528
1529void scene::draw_lines_cij_with_selection(int *selection, int nb_select,
1530 ostream &ost)
1531{
1532 int i, j, h, s;
1533 numerics N;
1534
1535 ost << endl;
1536 ost << " union{ // cij lines" << endl;
1537 ost << endl;
1538 ost << " #declare r=" << line_radius << "; " << endl;
1539 //ost << " #declare b=4;" << endl;
1540 ost << endl;
1541 for (i = 0; i < nb_select; i++) {
1542 s = selection[i];
1543 j = 12 + s;
1544 ost << " cylinder{<";
1545 for (h = 0; h < 3; h++) {
1546 N.output_double(Line_coords[j * 6 + h], ost);
1547 if (h < 2) {
1548 ost << ", ";
1549 }
1550 }
1551 ost << ">,<";
1552 for (h = 0; h < 3; h++) {
1553 N.output_double(Line_coords[j * 6 + 3 + h], ost);
1554 if (h < 2) {
1555 ost << ", ";
1556 }
1557 }
1558 ost << ">, r } // line " << j << endl;
1559 }
1560 ost << endl;
1561 ost << " pigment{Yellow}" << endl;
1562 ost << " }" << endl;
1563}
1564
1565void scene::draw_lines_cij(ostream &ost)
1566{
1567 int selection[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};
1568
1569 draw_lines_cij_with_selection(selection, 15, ost);
1570}
1571
1572void scene::draw_lines_cij_with_offset(int offset, int number_of_lines, ostream &ost)
1573{
1574 int selection[15];
1575 int i;
1576
1577 for (i = 0; i < number_of_lines; i++) {
1578 selection[i] = offset + i;
1579 }
1580 draw_lines_cij_with_selection(selection, number_of_lines, ost);
1581}
1582
1583void scene::draw_lines_ai_with_selection(int *selection, int nb_select,
1584 ostream &ost)
1585{
1586 int s, i, j, h;
1587 numerics N;
1588
1589 ost << endl;
1590 ost << " union{ // ai lines" << endl;
1591 ost << endl;
1592 ost << " #declare r=" << line_radius << "; " << endl;
1593 //ost << " #declare b=4;" << endl;
1594 ost << endl;
1595 for (i = 0; i < nb_select; i++) {
1596 s = selection[i];
1597 j = 0 + s;
1598 ost << " cylinder{<";
1599 for (h = 0; h < 3; h++) {
1600 N.output_double(Line_coords[j * 6 + h], ost);
1601 if (h < 2) {
1602 ost << ", ";
1603 }
1604 }
1605 ost << ">,<";
1606 for (h = 0; h < 3; h++) {
1607 N.output_double(Line_coords[j * 6 + 3 + h], ost);
1608 if (h < 2) {
1609 ost << ", ";
1610 }
1611 }
1612 ost << ">, r } // line " << j << endl;
1613 }
1614 ost << endl;
1615 ost << " pigment{Red}" << endl;
1616 ost << " }" << endl;
1617}
1618
1619void scene::draw_lines_ai(ostream &ost)
1620{
1621 int selection[] = {0,1,2,3,4,5};
1622
1623 draw_lines_ai_with_selection(selection, 6, ost);
1624}
1625
1626void scene::draw_lines_ai_with_offset(int offset, ostream &ost)
1627{
1628 int selection[6];
1629 int i;
1630
1631 for (i = 0; i < 6; i++) {
1632 selection[i] = offset + i;
1633 }
1634 draw_lines_ai_with_selection(selection, 6, ost);
1635}
1636
1637void scene::draw_lines_bj_with_selection(int *selection, int nb_select,
1638 ostream &ost)
1639{
1640 int s, i, j, h;
1641 numerics N;
1642
1643 ost << endl;
1644 ost << " union{ // bj lines" << endl;
1645 ost << endl;
1646 ost << " #declare r=" << line_radius << "; " << endl;
1647 //ost << " #declare b=4;" << endl;
1648 ost << endl;
1649 for (i = 0; i < nb_select; i++) {
1650 s = selection[i];
1651 j = 6 + s;
1652 ost << " cylinder{<";
1653 for (h = 0; h < 3; h++) {
1654 N.output_double(Line_coords[j * 6 + h], ost);
1655 if (h < 2) {
1656 ost << ", ";
1657 }
1658 }
1659 ost << ">,<";
1660 for (h = 0; h < 3; h++) {
1661 N.output_double(Line_coords[j * 6 + 3 + h], ost);
1662 if (h < 2) {
1663 ost << ", ";
1664 }
1665 }
1666 ost << ">, r } // line " << j << endl;
1667 }
1668 ost << endl;
1669 ost << " pigment{Blue}" << endl;
1670 ost << " }" << endl;
1671}
1672
1673void scene::draw_lines_bj(ostream &ost)
1674{
1675 int selection[] = {0,1,2,3,4,5};
1676
1677 draw_lines_bj_with_selection(selection, 6, ost);
1678}
1679
1680void scene::draw_lines_bj_with_offset(int offset, ostream &ost)
1681{
1682 int selection[6];
1683 int i;
1684
1685 for (i = 0; i < 6; i++) {
1686 selection[i] = offset + i;
1687 }
1688 draw_lines_bj_with_selection(selection, 6, ost);
1689}
1690
1691
1692
1693
1694void scene::draw_edges_with_selection(int *selection, int nb_select,
1695 std::string &options, ostream &ost)
1696{
1697 int s, i, j, h, pt1, pt2;
1698 numerics N;
1699
1700 ost << endl;
1701 ost << " union{ // edges" << endl;
1702 ost << endl;
1703 ost << " #declare r=" << line_radius << " ; " << endl;
1704 ost << endl;
1705 for (i = 0; i < nb_select; i++) {
1706 s = selection[i];
1707 j = s;
1708 pt1 = Edge_points[j * 2 + 0];
1709 pt2 = Edge_points[j * 2 + 1];
1710 ost << " cylinder{<";
1711 for (h = 0; h < 3; h++) {
1712 N.output_double(Point_coords[pt1 * 3 + h], ost);
1713 if (h < 2) {
1714 ost << ", ";
1715 }
1716 }
1717 ost << ">,<";
1718 for (h = 0; h < 3; h++) {
1719 N.output_double(Point_coords[pt2 * 3 + h], ost);
1720 if (h < 2) {
1721 ost << ", ";
1722 }
1723 }
1724 ost << ">, r } // line " << j << endl;
1725 }
1726 ost << endl;
1727 ost << " " << options << " " << endl;
1728 //ost << " pigment{" << color << "}" << endl;
1729 ost << " }" << endl;
1730}
1731
1732void scene::draw_faces_with_selection(int *selection, int nb_select,
1733 double thickness_half, std::string &options, ostream &ost)
1734{
1735 int s, i, j;
1736
1737 ost << endl;
1738 ost << " union{ // faces" << endl;
1739 ost << endl;
1740 //ost << " #declare r=" << rad << " ; " << endl;
1741 //ost << endl;
1742 for (i = 0; i < nb_select; i++) {
1743 s = selection[i];
1744 j = s;
1745 ost << "\t\t// face " << j << ":" << endl;
1746 draw_face(j, thickness_half, options, ost);
1747 }
1748 ost << endl;
1749 //ost << " pigment{" << color << "}" << endl;
1750 ost << " }" << endl;
1751}
1752
1753
1754void scene::draw_face(int idx, double thickness_half, std::string &options,
1755 ostream &ost)
1756{
1757 int f_v = FALSE;
1758 int *pts;
1759 int nb_pts, i;
1760 double *Pts_in;
1761 double *Pts_out;
1762 double abc3[3];
1763 double angles3[3];
1764 double T3[3];
1765 numerics N;
1766
1767 nb_pts = Nb_face_points[idx];
1768 pts = Face_points[idx];
1769 Pts_in = new double [nb_pts * 3];
1770 Pts_out = new double [nb_pts * 2];
1771 if (f_v) {
1772 cout << "scene::draw_face" << endl;
1773 }
1774 for (i = 0; i < nb_pts; i++) {
1775 N.vec_copy(Point_coords + pts[i] * 3, Pts_in + i * 3, 3);
1776 if (f_v) {
1777 cout << "vertex i= " << i << " pts[i] = " << pts[i]
1778 << " x=" << Pts_in[i * 3 + 0]
1779 << " y=" << Pts_in[i * 3 + 1]
1780 << " z=" << Pts_in[i * 3 + 2]
1781 << endl;
1782 }
1783 }
1784
1785#if 0
1786 N.triangular_prism(P1, P2, P3,
1787 abc3, angles3, T3,
1788 0 /*verbose_level*/);
1789#else
1790 N.general_prism(Pts_in, nb_pts, Pts_out,
1791 abc3, angles3, T3,
1792 0 /*verbose_level*/);
1793#endif
1794
1795
1796
1797 //double thickness_half = 0.001;
1798
1799 ost << "\t\tprism { ";
1800 N.output_double(-thickness_half, ost);
1801 ost << ", ";
1802 N.output_double(thickness_half, ost);
1803 ost << ", " << nb_pts + 1 << endl;
1804 ost << "\t\t\t< 0, 0 >," << endl;
1805 ost << "\t\t\t< ";
1806 N.output_double(abc3[0], ost);
1807 ost << ", " << 0 << " >," << endl;
1808 ost << "\t\t\t< ";
1809 N.output_double(abc3[1], ost);
1810 ost << ", ";
1811 N.output_double(abc3[2], ost);
1812 ost << " >," << endl;
1813 for (i = 3; i < nb_pts; i++) {
1814 ost << "\t\t\t< ";
1815 N.output_double(Pts_out[i * 2 + 0], ost);
1816 ost << ", ";
1817 N.output_double(Pts_out[i * 2 + 1], ost);
1818 ost << " >," << endl;
1819 }
1820 ost << "\t\t\t< 0, 0 >" << endl;
1821 ost << "\t\t\t " << options << " " << endl;
1822 //ost << "\t\t\ttexture{ " << endl;
1823 //ost << "\t\t\t\tpigment{color " << color << " }" << endl;
1824 //ost << "\t\t\t\tfinish {ambient 0.4 diffuse 0.5 "
1825 //"roughness 0.001 reflection 0.1 specular .8}" << endl;
1826 //ost << "\t\t\t}" << endl;
1827 //ost << "rotate<" << -90 << ",0,0>" << endl;
1828 ost << "\t\trotate<";
1829 N.output_double(N.rad2deg(angles3[0]), ost);
1830 ost << ",0,0>" << endl;
1831 ost << "\t\trotate<0, ";
1832 N.output_double(N.rad2deg(angles3[1]), ost);
1833 ost << ",0>" << endl;
1834 ost << "\t\trotate<0,0, ";
1835 N.output_double(N.rad2deg(angles3[2]), ost);
1836 ost << ">" << endl;
1837 ost << "\t\ttranslate<";
1838 N.output_double(T3[0], ost);
1839 ost << ", ";
1840 N.output_double(T3[1], ost);
1841 ost << ", ";
1842 N.output_double(T3[2], ost);
1843 ost << ">" << endl;
1844 ost << "\t\t}" << endl;
1845
1846 delete [] Pts_in;
1847 delete [] Pts_out;
1848}
1849
1850
1852 int *selection, int nb_select,
1853 std::string &options, ostream &ost)
1854// for instance color = "Orange transmit 0.5 "
1855{
1856 int i, j, h, s;
1857 numerics N;
1858
1859 ost << endl;
1860 ost << " union{ // planes" << endl;
1861 ost << endl;
1862 ost << endl;
1863 for (i = 0; i < nb_select; i++) {
1864 s = selection[i];
1865 j = s;
1866 ost << " plane{<";
1867 for (h = 0; h < 3; h++) {
1868 N.output_double(Plane_coords[j * 4 + h], ost);
1869 if (h < 2) {
1870 ost << ", ";
1871 }
1872 }
1873 ost << ">, ";
1874 N.output_double(Plane_coords[j * 4 + 3], ost);
1875 ost << "}" << endl;
1876 }
1877 ost << endl;
1878 ost << " " << options << " " << endl;
1879 //ost << " texture{ pigment{ color " << color << "}}" << endl;
1880 ost << " }" << endl;
1881}
1882
1884 int idx,
1885 std::string &options, ostream &ost)
1886// for instance color = "Orange transmit 0.5 "
1887{
1888 int h;
1889 numerics N;
1890
1891 ost << endl;
1892 ost << endl;
1893 ost << " object{" << endl;
1894 ost << " plane{<";
1895 for (h = 0; h < 3; h++) {
1896 N.output_double(Plane_coords[idx * 4 + h], ost);
1897 if (h < 2) {
1898 ost << ", ";
1899 }
1900 }
1901 ost << ">, ";
1902 N.output_double(Plane_coords[idx * 4 + 3], ost);
1903 ost << "}" << endl;
1904 ost << " " << options << " " << endl;
1905 //ost << " texture{ pigment{ color " << color << "}}" << endl;
1906 ost << " }" << endl;
1907}
1908
1909
1911 int *selection, int nb_select,
1912 double rad, std::string &options, ostream &ost)
1913// rad = 0.06 works
1914{
1915 int i, j, h, s;
1916 numerics N;
1917
1918 ost << endl;
1919 ost << " union{ // points" << endl;
1920 ost << endl;
1921 ost << " #declare r=" << rad << ";" << endl;
1922 ost << endl;
1923 for (i = 0; i < nb_select; i++) {
1924 s = selection[i];
1925 j = s;
1926 ost << " sphere{<";
1927 for (h = 0; h < 3; h++) {
1928 N.output_double(Point_coords[j * 3 + h], ost);
1929 if (h < 2) {
1930 ost << ", ";
1931 }
1932 }
1933 ost << ">, r }" << endl;
1934 }
1935 //ost << endl;
1936 ost << " " << options << " " << endl;
1937 //ost << " pigment{" << color << "}" << endl;
1938 //ost << " pigment{Cyan*1.3}" << endl;
1939 //ost << " finish {ambient 0.4 diffuse 0.6 roughness 0.001 "
1940 //"reflection 0 specular .8} " << endl;
1941 ost << " }" << endl;
1942}
1943
1944void scene::draw_cubic_with_selection(int *selection, int nb_select,
1945 std::string &options, std::ostream &ost)
1946{
1947 int i, j, h, s;
1948 numerics N;
1949
1950 ost << endl;
1951 ost << " union{ // cubics" << endl;
1952 ost << endl;
1953 for (i = 0; i < nb_select; i++) {
1954 s = selection[i];
1955 j = s;
1956
1957 cout << "scene::draw_cubic_with_selection j=" << j << ":" << endl;
1958 for (h = 0; h < 20; h++) {
1959 cout << h << " : " << Cubic_coords[j * 20 + h] << endl;
1960 }
1961 ost << " poly{3, <";
1962
1963 for (h = 0; h < 20; h++) {
1964 N.output_double(Cubic_coords[j * 20 + h], ost);
1965 if (h < 20 - 1) {
1966 ost << ", ";
1967 }
1968 }
1969 ost << ">";
1970 }
1971 ost << endl;
1972 ost << " " << options << " " << endl;
1973 //ost << " pigment{" << color << "}" << endl;
1974 //ost << " pigment{Cyan*1.3}" << endl;
1975 //ost << " finish {ambient 0.4 diffuse 0.5 roughness 0.001 "
1976 //"reflection 0.1 specular .8} " << endl;
1977 ost << " }" << endl;
1978 ost << " }" << endl;
1979}
1980
1981void scene::draw_quartic_with_selection(int *selection, int nb_select,
1982 std::string &options, std::ostream &ost)
1983{
1984 int i, j, h, s;
1985 numerics N;
1986
1987 ost << endl;
1988 ost << " union{ // quartics" << endl;
1989 ost << endl;
1990 for (i = 0; i < nb_select; i++) {
1991 s = selection[i];
1992 j = s;
1993
1994 cout << "scene::draw_quartic_with_selection j=" << j << ":" << endl;
1995 for (h = 0; h < 35; h++) {
1996 cout << h << " : " << Quartic_coords[j * 35 + h] << endl;
1997 }
1998 ost << " poly{4, <";
1999
2000 for (h = 0; h < 35; h++) {
2001 N.output_double(Quartic_coords[j * 35 + h], ost);
2002 if (h < 35 - 1) {
2003 ost << ", ";
2004 }
2005 }
2006 ost << ">";
2007 }
2008 ost << endl;
2009 ost << " " << options << " " << endl;
2010 //ost << " pigment{" << color << "}" << endl;
2011 //ost << " pigment{Cyan*1.3}" << endl;
2012 //ost << " finish {ambient 0.4 diffuse 0.5 roughness 0.001 "
2013 //"reflection 0.1 specular .8} " << endl;
2014 ost << " }" << endl;
2015 ost << " }" << endl;
2016}
2017
2018void scene::draw_quintic_with_selection(int *selection, int nb_select,
2019 std::string &options, std::ostream &ost)
2020{
2021 int i, j, h, s;
2022 numerics N;
2023
2024 ost << endl;
2025 ost << " union{ // quintics" << endl;
2026 ost << endl;
2027 for (i = 0; i < nb_select; i++) {
2028 s = selection[i];
2029 j = s;
2030
2031 cout << "scene::draw_quintic_with_selection j=" << j << ":" << endl;
2032 for (h = 0; h < 56; h++) {
2033 cout << h << " : " << Quintic_coords[j * 56 + h] << endl;
2034 }
2035 ost << " poly{5, <";
2036
2037 for (h = 0; h < 56; h++) {
2038 N.output_double(Quintic_coords[j * 56 + h], ost);
2039 if (h < 56 - 1) {
2040 ost << ", ";
2041 }
2042 }
2043 ost << ">";
2044 }
2045 ost << endl;
2046 ost << " " << options << " " << endl;
2047 //ost << " pigment{" << color << "}" << endl;
2048 //ost << " pigment{Cyan*1.3}" << endl;
2049 //ost << " finish {ambient 0.4 diffuse 0.5 roughness 0.001 "
2050 //"reflection 0.1 specular .8} " << endl;
2051 ost << " }" << endl;
2052 ost << " }" << endl;
2053}
2054
2055void scene::draw_octic_with_selection(int *selection, int nb_select,
2056 std::string &options, std::ostream &ost)
2057{
2058 int i, j, h, s;
2059 numerics N;
2060
2061 ost << endl;
2062 ost << " union{ // octics" << endl;
2063 ost << endl;
2064 for (i = 0; i < nb_select; i++) {
2065 s = selection[i];
2066 j = s;
2067
2068 cout << "scene::draw_quartic_with_selection j=" << j << ":" << endl;
2069 for (h = 0; h < 165; h++) {
2070 cout << h << " : " << Quartic_coords[j * 165 + h] << endl;
2071 }
2072 ost << " poly{8, <";
2073
2074 for (h = 0; h < 165; h++) {
2075 N.output_double(Octic_coords[j * 165 + h], ost);
2076 if (h < 165 - 1) {
2077 ost << ", ";
2078 }
2079 }
2080 ost << ">";
2081 }
2082 ost << endl;
2083 ost << " " << options << " " << endl;
2084 //ost << " pigment{" << color << "}" << endl;
2085 //ost << " pigment{Cyan*1.3}" << endl;
2086 //ost << " finish {ambient 0.4 diffuse 0.5 roughness 0.001 "
2087 //"reflection 0.1 specular .8} " << endl;
2088 ost << " }" << endl;
2089 ost << " }" << endl;
2090}
2091
2092void scene::draw_quadric_with_selection(int *selection, int nb_select,
2093 std::string &options, ostream &ost)
2094{
2095 int i, j, h, s;
2096 numerics N;
2097
2098 ost << endl;
2099 ost << " union{ // quadrics" << endl;
2100 ost << endl;
2101 for (i = 0; i < nb_select; i++) {
2102 s = selection[i];
2103 j = s;
2104 ost << " poly{2, <";
2105
2106 for (h = 0; h < 10; h++) {
2107 N.output_double(Quadric_coords[j * 10 + h], ost);
2108 if (h < 10 - 1) {
2109 ost << ", ";
2110 }
2111 }
2112 ost << ">}" << endl;
2113 }
2114 ost << endl;
2115 ost << " " << options << " " << endl;
2116 //ost << " texture{ pigment{" << color << "}}" << endl;
2117 //ost << " pigment{Cyan*1.3}" << endl;
2118 //ost << " finish { phong albedo 0.9 phong_size 60 ambient 0.4 "
2119 //"diffuse 0.5 roughness 0.001 reflection 0.1 specular .8} " << endl;
2120 ost << " }" << endl;
2121}
2122
2123void scene::draw_quadric_clipped_by_plane(int quadric_idx, int plane_idx,
2124 std::string &options, ostream &ost)
2125{
2126 int h;
2127 numerics N;
2128
2129 ost << endl;
2130 ost << " object{ // quadric clipped by plane" << endl;
2131 ost << endl;
2132 ost << " poly{2, <";
2133 for (h = 0; h < 10; h++) {
2134 N.output_double(Quadric_coords[quadric_idx * 10 + h], ost);
2135 if (h < 10 - 1) {
2136 ost << ", ";
2137 }
2138 }
2139 ost << ">}" << endl;
2140 ost << " clipped_by{ plane{<";
2141 N.output_double(Plane_coords[plane_idx * 4 + 0], ost);
2142 ost << ",";
2143 N.output_double(Plane_coords[plane_idx * 4 + 1], ost);
2144 ost << ",";
2145 N.output_double(Plane_coords[plane_idx * 4 + 2], ost);
2146 ost << ">,";
2147 N.output_double(Plane_coords[plane_idx * 4 + 3], ost);
2148 ost << "}";
2149 ost << "}" << endl;
2150
2151
2152 ost << endl;
2153 ost << " " << options << " " << endl;
2154 //ost << " texture{ pigment{" << color << "}}" << endl;
2155 //ost << " pigment{Cyan*1.3}" << endl;
2156 //ost << " finish { phong albedo 0.9 phong_size 60 ambient 0.4 "
2157 //"diffuse 0.5 roughness 0.001 reflection 0.1 specular .8} " << endl;
2158 ost << " }" << endl;
2159}
2160
2161
2162void scene::draw_line_clipped_by_plane(int line_idx, int plane_idx,
2163 std::string &options, ostream &ost)
2164{
2165 int h;
2166 numerics N;
2167
2168 ost << endl;
2169 ost << " object{ // line with clipping" << endl;
2170 ost << endl;
2171 ost << " #declare r=" << line_radius << "; " << endl;
2172 //ost << " #declare b=4;" << endl;
2173 ost << endl;
2174 ost << " cylinder{<";
2175 for (h = 0; h < 3; h++) {
2176 N.output_double(Line_coords[line_idx * 6 + h], ost);
2177 if (h < 2) {
2178 ost << ", ";
2179 }
2180 }
2181 ost << ">,<";
2182 for (h = 0; h < 3; h++) {
2183 N.output_double(Line_coords[line_idx * 6 + 3 + h], ost);
2184 if (h < 2) {
2185 ost << ", ";
2186 }
2187 }
2188 ost << ">, r }" << endl;
2189 ost << " clipped_by{ plane{<";
2190 N.output_double(Plane_coords[plane_idx * 4 + 0], ost);
2191 ost << ",";
2192 N.output_double(Plane_coords[plane_idx * 4 + 1], ost);
2193 ost << ",";
2194 N.output_double(Plane_coords[plane_idx * 4 + 2], ost);
2195 ost << ">,";
2196 N.output_double(Plane_coords[plane_idx * 4 + 3], ost);
2197 ost << "}";
2198 ost << "}" << endl;
2199 ost << endl;
2200 ost << " " << options << "" << endl;
2201 //ost << " pigment{" << color << "}" << endl;
2202 ost << " }" << endl;
2203}
2204
2205
2206
2207
2208
2209int scene::intersect_line_and_plane(int line_idx, int plane_idx,
2210 int &intersection_point_idx,
2211 int verbose_level)
2212{
2213 int f_v = (verbose_level >= 1);
2214 int f_vv = FALSE; // (verbose_level >= 2);
2215 double B[9];
2216 double M[12];
2217 int i;
2218 double a, av;
2219 double v[3];
2220 numerics N;
2222
2223 if (f_v) {
2224 cout << "scene::intersect_line_and_plane" << endl;
2225 }
2226 if (f_v) {
2227 cout << "scene::intersect_line_and_plane line_idx=" << line_idx << endl;
2228 cout << "scene::intersect_line_and_plane plane_idx=" << plane_idx << endl;
2229 print_a_line(line_idx);
2230 print_a_plane(plane_idx);
2231 }
2232
2233
2234 // equation of the form:
2235 // P_0 + \lambda * v = Q_0 + \mu * u + \nu * w
2236
2237 // where P_0 is a point on the line,
2238 // Q_0 is a point on the plane,
2239 // v is a direction vector of the line
2240 // u, w are vectors which span the plane.
2241
2242 // M is the matrix whose columns are
2243 // v, -u, -w, -P_0 + Q_0
2244
2245 // point on the line, brought over on the other side, hence the minus:
2246 // -P_0
2247 M[0 * 4 + 3] = -1. * Line_coords[line_idx * 6 + 0];
2248 M[1 * 4 + 3] = -1. * Line_coords[line_idx * 6 + 1];
2249 M[2 * 4 + 3] = -1. * Line_coords[line_idx * 6 + 2];
2250
2251 // direction vector of the line:
2252 // we will need v[] later, hence we store this vector
2253 for (i = 0; i < 3; i++) {
2254 v[i] = Line_coords[line_idx * 6 + 3 + i] -
2255 Line_coords[line_idx * 6 + i];
2256 M[i * 4 + 0] = v[i];
2257 }
2258
2259 if (f_v) {
2260 cout << "scene::intersect_line_and_plane M=" << endl;
2261 numerics Num;
2262
2263 Num.print_system(M, 3, 4);
2264 }
2265
2266 // compute the vectors u and w:
2267 B[0 * 3 + 0] = Plane_coords[plane_idx * 4 + 0];
2268 B[0 * 3 + 1] = Plane_coords[plane_idx * 4 + 1];
2269 B[0 * 3 + 2] = Plane_coords[plane_idx * 4 + 2];
2270
2271 int b1, b2;
2272 if (ABS(B[0 * 3 + 0]) > EPSILON) {
2273 a = 1. / B[0 * 3 + 0];
2274 for (i = 0; i < 3; i++) {
2275 B[i] *= a;
2276 }
2277 B[1 * 3 + 0] = 0.;
2278 B[1 * 3 + 1] = -1.;
2279 B[1 * 3 + 2] = 0.;
2280 B[2 * 3 + 0] = 0.;
2281 B[2 * 3 + 1] = 0.;
2282 B[2 * 3 + 2] = -1.;
2283 b1 = 1;
2284 b2 = 2;
2285 }
2286 else {
2287 if (f_v) {
2288 cout << "scene::intersect_line_and_plane "
2289 "ABS(B[0 * 3 + 0]) is too small" << endl;
2290 }
2291 if (ABS(B[0 * 3 + 1]) > EPSILON) {
2292 a = 1. / B[0 * 3 + 1];
2293 for (i = 0; i < 3; i++) {
2294 B[3 + i] = B[i] * a;
2295 }
2296 B[0 * 3 + 0] = -1.;
2297 B[0 * 3 + 1] = 0;
2298 B[0 * 3 + 2] = 0.;
2299 B[2 * 3 + 0] = 0.;
2300 B[2 * 3 + 1] = 0.;
2301 B[2 * 3 + 2] = -1.;
2302 b1 = 0;
2303 b2 = 2;
2304 }
2305 else {
2306 if (f_v) {
2307 cout << "scene::intersect_line_and_plane "
2308 "ABS(B[0 * 3 + 0]) and ABS(B[0 * 3 + 1]) are too small" << endl;
2309 }
2310 if (ABS(B[0 * 3 + 2]) > EPSILON) {
2311 a = 1. / B[0 * 3 + 2];
2312 for (i = 0; i < 3; i++) {
2313 B[6 + i] = B[i] * a;
2314 }
2315 B[0 * 3 + 0] = -1.;
2316 B[0 * 3 + 1] = 0;
2317 B[0 * 3 + 2] = 0.;
2318 B[1 * 3 + 0] = 0.;
2319 B[1 * 3 + 1] = -1.;
2320 B[1 * 3 + 2] = 0;
2321 b1 = 0;
2322 b2 = 1;
2323 }
2324 else {
2325 cout << "scene::intersect_line_and_plane the first three entries of B are zero" << endl;
2326 exit(1);
2327 }
2328 }
2329 }
2330 // copy u:
2331 M[0 * 4 + 1] = -1. * B[0 * 3 + b1];
2332 M[1 * 4 + 1] = -1. * B[1 * 3 + b1];
2333 M[2 * 4 + 1] = -1. * B[2 * 3 + b1];
2334 // copy w:
2335 M[0 * 4 + 2] = -1. * B[0 * 3 + b2];
2336 M[1 * 4 + 2] = -1. * B[1 * 3 + b2];
2337 M[2 * 4 + 2] = -1. * B[2 * 3 + b2];
2338
2339 // find Q_0:
2340
2341 while (TRUE) {
2342 B[0] = (double) Os.random_integer(5);
2343 B[1] = (double) Os.random_integer(5);
2344 B[2] = (double) Os.random_integer(5);
2345 a = B[0] * Plane_coords[plane_idx * 4 + 0];
2346 a += B[1] * Plane_coords[plane_idx * 4 + 1];
2347 a += B[2] * Plane_coords[plane_idx * 4 + 2];
2348 if (ABS(a) > EPSILON) {
2349 break;
2350 }
2351 }
2352 av = (1. / a) * Plane_coords[plane_idx * 4 + 3];
2353 for (i = 0; i < 3; i++) {
2354 B[i] *= av;
2355 }
2356 // add Q_0 onto the RHS:
2357 M[0 * 4 + 3] += B[0];
2358 M[1 * 4 + 3] += B[1];
2359 M[2 * 4 + 3] += B[2];
2360
2361 // solve M:
2362 int rk;
2363 int base_cols[4];
2364 double lambda;
2365
2366 if (f_vv) {
2367 cout << "scene::intersect_line_and_plane "
2368 "before Gauss elimination:" << endl;
2369 N.print_system(M, 3, 4);
2370 }
2371
2372 rk = N.Gauss_elimination(M, 3, 4,
2373 base_cols, TRUE /* f_complete */,
2374 0 /* verbose_level */);
2375
2376 if (f_vv) {
2377 cout << "scene::intersect_line_and_plane "
2378 "after Gauss elimination:" << endl;
2379 N.print_system(M, 3, 4);
2380 }
2381
2382
2383 if (rk < 3) {
2384 cout << "scene::intersect_line_and_plane "
2385 "the matrix M does not have full rank" << endl;
2386 return FALSE;
2387 }
2388 lambda = 1. * M[0 * 4 + 3];
2389 for (i = 0; i < 3; i++) {
2390 B[i] = Line_coords[line_idx * 6 + i] + lambda * v[i];
2391 }
2392
2393 if (f_vv) {
2394 cout << "scene::intersect_line_and_plane "
2395 "The intersection point is "
2396 << B[0] << ", " << B[1] << ", " << B[2] << endl;
2397 }
2398 point(B[0], B[1], B[2]);
2399
2400 intersection_point_idx = nb_points - 1;
2401
2402 if (f_v) {
2403 cout << "scene::intersect_line_and_plane done" << endl;
2404 }
2405 return TRUE;
2406}
2407
2408int scene::intersect_line_and_line(int line1_idx, int line2_idx,
2409 double &lambda,
2410 int verbose_level)
2411{
2412 int f_v = (verbose_level >= 1);
2413 //int f_vv = FALSE; // (verbose_level >= 2);
2414 numerics N;
2415
2416 if (f_v) {
2417 cout << "scene::intersect_line_and_line" << endl;
2418 }
2419
2420 double pt_coords[3];
2421
2423 &Line_coords[line1_idx * 6 + 0], &Line_coords[line1_idx * 6 + 3],
2424 &Line_coords[line2_idx * 6 + 0], &Line_coords[line2_idx * 6 + 3],
2425 lambda,
2426 pt_coords,
2427 verbose_level - 2);
2428
2429 point(pt_coords[0], pt_coords[1], pt_coords[2]);
2430
2431 if (f_v) {
2432 cout << "scene::intersect_line_and_line done" << endl;
2433 }
2434 return TRUE;
2435}
2436
2437
2439 double x1, double x2, double x3,
2440 double y1, double y2, double y3, double r)
2441{
2442 //double d1, d2;
2443 double v[3];
2444 double a, b, c, av, d, e;
2445 double lambda1, lambda2;
2446
2447 //d1 = ::distance_from_origin(x1, x2, x3);
2448 //d2 = ::distance_from_origin(y1, y2, y3);
2449 v[0] = y1 - x1;
2450 v[1] = y2 - x2;
2451 v[2] = y3 - x3;
2452 // solve
2453 // (x1+\lambda*v[0])^2 + (x2+\lambda*v[1])^2 + (x3+\lambda*v[2])^2 = r^2
2454 // which gives
2455 // (v[0]^2+v[1]^2+v[2]^2) * \lambda^2 +
2456 // (2*x1*v[0] + 2*x2*v[1] + 2*x3*v[2]) * \lambda +
2457 // x1^2 + x2^2 + x3^2 - r^2 = 0
2458 a = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
2459 b = 2 * (x1 * v[0] + x2 * v[1] + x3 * v[2]);
2460 c = x1 * x1 + x2 * x2 + x3 * x3 - r * r;
2461 av = 1. / a;
2462 b = b * av;
2463 c = c * av;
2464 d = b * b * 0.25 - c;
2465 if (d < 0) {
2466 cout << "line_extended d < 0" << endl;
2467 return line(x1, x2, x3, y1, y2, y3);
2468 }
2469 e = sqrt(d);
2470 lambda1 = -b * 0.5 + e;
2471 lambda2 = -b * 0.5 - e;
2472 Line_coords[nb_lines * 6 + 0] = x1 + lambda1 * v[0];
2473 Line_coords[nb_lines * 6 + 1] = x2 + lambda1 * v[1];
2474 Line_coords[nb_lines * 6 + 2] = x3 + lambda1 * v[2];
2475 Line_coords[nb_lines * 6 + 3] = x1 + lambda2 * v[0];
2476 Line_coords[nb_lines * 6 + 4] = x2 + lambda2 * v[1];
2477 Line_coords[nb_lines * 6 + 5] = x3 + lambda2 * v[2];
2478 nb_lines++;
2479 if (nb_lines >= SCENE_MAX_LINES) {
2480 cout << "too many lines" << endl;
2481 exit(1);
2482 }
2483 return nb_lines - 1;
2484}
2485
2486void scene::map_a_line(int line1, int line2,
2487 int plane_idx, int line_idx, double spread,
2488 int nb_pts,
2489 int *New_line_idx, int &nb_new_lines,
2490 int *New_pt_idx, int &nb_new_points,
2491 int verbose_level)
2492{
2493 int f_v = (verbose_level >= 1);
2494 double line_pt1_in[3], line_pt2_in[3];
2495 double line_pt1[3], line_pt2[3];
2496 double direction[3], direction_step[3];
2497 double line_pt[3];
2498 int i, h;
2499 numerics N;
2500
2501 if (f_v) {
2502 cout << "map_a_line" << endl;
2503 }
2504
2505 nb_new_lines = 0;
2506 nb_new_points = 0;
2507 N.vec_copy(Line_coords + line_idx * 6, line_pt1_in, 3);
2508 N.vec_copy(Line_coords + line_idx * 6 + 3, line_pt2_in, 3);
2509 N.line_centered(line_pt1_in, line_pt2_in,
2510 line_pt1, line_pt2, spread /* r */, verbose_level - 1);
2511
2512 for (i = 0; i < 3; i++) {
2513 direction[i] = line_pt2[i] - line_pt1[i];
2514 }
2515 for (i = 0; i < 3; i++) {
2516 direction_step[i] = direction[i] / (double) (nb_pts - 1);
2517 }
2518 for (h = 0; h < nb_pts; h++) {
2519 if (f_v) {
2520 cout << "map_a_line point " << h << " / "
2521 << nb_pts << ":" << endl;
2522 }
2523 for (i = 0; i < 3; i++) {
2524 line_pt[i] = line_pt1[i] + (double) h * direction_step[i];
2525 }
2526
2527 New_pt_idx[nb_new_points] = point(line_pt[0], line_pt[1], line_pt[2]);
2528 nb_new_points++;
2529
2530 if (map_a_point(line1, line2, plane_idx, line_pt,
2531 New_line_idx[nb_new_lines], New_pt_idx[nb_new_points],
2532 verbose_level)) {
2533
2534 nb_new_lines++;
2535 nb_new_points++;
2536 }
2537 }
2538
2539
2540 if (f_v) {
2541 cout << "map_a_line done" << endl;
2542 }
2543}
2544
2545int scene::map_a_point(int line1, int line2,
2546 int plane_idx, double pt_in[3],
2547 int &new_line_idx, int &new_pt_idx,
2548 int verbose_level)
2549{
2550 int f_v = (verbose_level >= 1);
2551 int f_vv = FALSE; //(verbose_level >= 2);
2552 double line1_pt1[4], line1_pt2[4];
2553 double line2_pt1[4], line2_pt2[4];
2554 double M1[4 * 4];
2555 double M2[4 * 4];
2556 double K1[4 * 4];
2557 double K2[4 * 4];
2558 double K3[4 * 4];
2559 double K4[4 * 4];
2560 int k1, k2, k3, i;
2561 numerics N;
2562
2563 if (f_v) {
2564 cout << "map_a_point" << endl;
2565 }
2566
2567 N.vec_copy(Line_coords + line1 * 6, line1_pt1, 3);
2568 line1_pt1[3] = 1.;
2569 N.vec_copy(Line_coords + line1 * 6 + 3, line1_pt2, 3);
2570 line1_pt2[3] = 1.;
2571
2572 N.vec_copy(Line_coords + line2 * 6, line2_pt1, 3);
2573 line2_pt1[3] = 1.;
2574 N.vec_copy(Line_coords + line2 * 6 + 3, line2_pt2, 3);
2575 line2_pt2[3] = 1.;
2576
2577 N.vec_copy(line1_pt1, M1, 4);
2578 N.vec_copy(line1_pt2, M1 + 4, 4);
2579 N.vec_copy(pt_in, M1 + 8, 3);
2580 M1[8 + 3] = 1.;
2581 if (f_vv) {
2582 cout << "M1:" << endl;
2583 N.print_system(M1, 3, 4);
2584 }
2585
2586 N.vec_copy(line2_pt1, M2, 4);
2587 N.vec_copy(line2_pt2, M2 + 4, 4);
2588 N.vec_copy(pt_in, M2 + 8, 3);
2589 M2[8 + 3] = 1.;
2590 if (f_vv) {
2591 cout << "M2:" << endl;
2592 N.print_system(M1, 3, 4);
2593 }
2594
2595 k1 = N.Null_space(M1, 3, 4, K1, 0 /* verbose_level */);
2596 if (k1 != 1) {
2597 cout << "map_a_point k1 != 1" << endl;
2598 return FALSE;
2599 }
2600 if (f_vv) {
2601 cout << "M1 after:" << endl;
2602 N.print_system(M1, 3, 4);
2603 cout << "K1:" << endl;
2604 N.print_system(K1, 1, 4);
2605 }
2606
2607 k2 = N.Null_space(M2, 3, 4, K2, 0 /* verbose_level */);
2608 if (k2 != 1) {
2609 cout << "map_a_point k2 != 1" << endl;
2610 return FALSE;
2611 }
2612 if (f_vv) {
2613 cout << "K2:" << endl;
2614 N.print_system(K2, 1, 4);
2615 }
2616
2617 N.vec_copy(K1, K3, 4);
2618 N.vec_copy(K2, K3 + 4, 4);
2619 k3 = N.Null_space(K3, 2, 4, K4, 0 /* verbose_level */);
2620 if (k3 != 2) {
2621 cout << "map_a_point k3 != 2" << endl;
2622 return FALSE;
2623 }
2624 if (f_vv) {
2625 cout << "K4:" << endl;
2626 N.print_system(K4, 2, 4);
2627 }
2628
2629 N.vec_normalize_from_back(K4, 4);
2630 N.vec_normalize_from_back(K4 + 4, 4);
2631 if (ABS(K4[3] - 1.) > 0.01 && ABS(K4[4 + 3] - 1.) > 0.01) {
2632 cout << "K4 (1) and (2) are not affine points, "
2633 "this is not good" << endl;
2634 exit(1);
2635 }
2636 if (ABS(K4[3] - 1.) > 0.01) {
2637 for (i = 0; i < 4; i++) {
2638 K4[i] = K4[i] + K4[4 + i];
2639 }
2640 N.vec_normalize_from_back(K4, 4);
2641 if (ABS(K4[3] - 1.) > 0.01) {
2642 cout << "after fixing, K4 (1) is not an affine point, "
2643 "this is not good" << endl;
2644 return FALSE;
2645 }
2646 }
2647 else if (ABS(K4[4 + 3] - 1.) > 0.01) {
2648 for (i = 0; i < 4; i++) {
2649 K4[4 + i] = K4[i] + K4[4 + i];
2650 }
2651 N.vec_normalize_from_back(K4 + 4, 4);
2652 if (ABS(K4[4 + 3] - 1.) > 0.01) {
2653 cout << "after fixing, K4 (2) is not an affine point, "
2654 "this is not good" << endl;
2655 return FALSE;
2656 }
2657 }
2658 new_line_idx = line_extended(K4[0], K4[1], K4[2],
2659 K4[4 + 0], K4[4 + 1], K4[4 + 2], 10.);
2660
2661 intersect_line_and_plane(new_line_idx, plane_idx,
2662 new_pt_idx, 0 /* verbose_level */);
2663
2664 if (f_v) {
2665 cout << "map_a_point done" << endl;
2666 }
2667 return TRUE;
2668}
2669
2670void scene::fourD_cube(double rad_desired)
2671{
2672 int r, i, j, k, h;
2673 int v[3];
2674 double x[3];
2675 double rad;
2676
2677 int first_pt_idx;
2678
2679 first_pt_idx = nb_points;
2680 for (r = 0; r < 2; r++) {
2681 if (r == 0) {
2682 rad = 1;
2683 }
2684 else {
2685 rad = 2;
2686 }
2687 for (i = 0; i < 2; i++) {
2688 v[0] = i;
2689 for (j = 0; j < 2; j++) {
2690 v[1] = j;
2691 for (k = 0; k < 2; k++) {
2692 v[2] = k;
2693 for (h = 0; h < 3; h++) {
2694 if (v[h] == 1) {
2695 x[h] = -1 * rad;
2696 }
2697 else {
2698 x[h] = rad;
2699 }
2700 }
2701 point(x[0], x[1], x[2]);
2702 }
2703 }
2704 }
2705 }
2706 fourD_cube_edges(first_pt_idx);
2707
2708 rescale(first_pt_idx, rad_desired);
2709
2710}
2711
2712void scene::rescale(int first_pt_idx, double rad_desired)
2713{
2714 int i;
2715 double rad = 1., a;
2716 numerics N;
2717
2718 for (i = first_pt_idx; i < nb_points; i++) {
2720 Point_coords + i * 3, 3);
2721 if (i == first_pt_idx) {
2722 rad = a;
2723 }
2724 else {
2725 if (a > rad) {
2726 rad = a;
2727 }
2728 }
2729 }
2730 a = rad_desired / rad;
2731 N.vec_scalar_multiple(Point_coords + first_pt_idx * 3,
2732 a, 3 * (nb_points - first_pt_idx));
2733}
2734
2735double scene::euclidean_distance(int pt1, int pt2)
2736{
2737 double d;
2738 numerics N;
2739
2740 d = N.distance_euclidean(Point_coords + pt1 * 3, Point_coords + pt2 * 3, 3);
2741 return d;
2742}
2743
2745{
2746 double d;
2747 numerics N;
2748
2750 Point_coords[pt * 3 + 0],
2751 Point_coords[pt * 3 + 1], Point_coords[pt * 3 + 2]);
2752 return d;
2753}
2754
2755void scene::fourD_cube_edges(int first_pt_idx)
2756{
2757 int i, j;
2758 double d;
2759
2760 for (i = 0; i < 8; i++) {
2761 edge(first_pt_idx + i, first_pt_idx + 8 + i);
2762 }
2763 for (i = 0; i < 8; i++) {
2764 for (j = i + 1; j < 8; j++) {
2765 d = distance_between_two_points(first_pt_idx + i, first_pt_idx + j);
2766 cout << "i=" << i << " j=" << j << " d=" << d << endl;
2767 if (ABS(d - 2) < 0.2) {
2768 cout << "EDGE " << i << ", " << j << endl;
2769 edge(first_pt_idx + i, first_pt_idx + j);
2770 edge(first_pt_idx + 8 + i, first_pt_idx + 8 + j);
2771 }
2772 else {
2773 //cout << endl;
2774 }
2775 }
2776 }
2777}
2778
2779// tetrahedron vertices on the unit cube:
2780//v1 = ( sqrt(8/9), 0 , -1/3 )
2781//v2 = ( -sqrt(2/9), sqrt(2/3), -1/3 )
2782//v3 = ( -sqrt(2/9), -sqrt(2/3), -1/3 )
2783//v4 = ( 0 , 0 , 1 )
2784
2785
2786void scene::hypercube(int n, double rad_desired)
2787{
2788 int N, i, j, h, k, d;
2789 int *v;
2790 int *w;
2791 double *Basis; // [n * 3];
2792 double x[3];
2793 double t, dt;
2794 numerics Num;
2797
2798 int first_pt_idx;
2799
2800 first_pt_idx = nb_points;
2801 N = NT.i_power_j(2, n);
2802
2803 Basis = new double [n * 3];
2804 v = NEW_int(n);
2805 w = NEW_int(n);
2806
2807 if (n == 4) {
2808 Basis[0 * 3 + 0] = sqrt(8./9.);
2809 Basis[0 * 3 + 1] = 0;
2810 Basis[0 * 3 + 2] = -1 / 3.;
2811 Basis[1 * 3 + 0] = -sqrt(2./9.);
2812 Basis[1 * 3 + 1] = sqrt(2/3);
2813 Basis[1 * 3 + 2] = -1 / 3.;
2814 Basis[2 * 3 + 0] = -sqrt(2./9.);
2815 Basis[2 * 3 + 1] = -sqrt(2/3);
2816 Basis[2 * 3 + 2] = -1 / 3.;
2817 Basis[3 * 3 + 0] = 0;
2818 Basis[3 * 3 + 1] = 0;
2819 Basis[3 * 3 + 2] = -1 / 3.;
2820 }
2821 else {
2822 dt = 1. / (n - 1);
2823 for (i = 0; i < n; i++) {
2824 t = i * dt;
2825 Basis[i * 3 + 0] = cos(M_PI * t);
2826 Basis[i * 3 + 1] = sin(M_PI * t);
2827 Basis[i * 3 + 2] = t;
2828 }
2829 }
2830 for (i = 0; i < n; i++) {
2831 Num.make_unit_vector(Basis + i * 3, 3);
2832 }
2833
2834 for (h = 0; h < N; h++) {
2835 Gg.AG_element_unrank(2, v, 1, n, h);
2836 for (j = 0; j < 3; j++) {
2837 x[j] = 0.;
2838 }
2839 for (i = 0; i < n; i++) {
2840 if (v[i]) {
2841 for (j = 0; j < 3; j++) {
2842 x[j] += Basis[i * 3 + j];
2843 }
2844 }
2845 else {
2846 for (j = 0; j < 3; j++) {
2847 x[j] -= Basis[i * 3 + j];
2848 }
2849 }
2850 }
2851 point(x[0], x[1], x[2]);
2852 }
2853 for (h = 0; h < N; h++) {
2854 Gg.AG_element_unrank(2, v, 1, n, h);
2855 for (k = h + 1; k < N; k++) {
2856 Gg.AG_element_unrank(2, w, 1, n, k);
2857 d = 0;
2858 for (i = 0; i < n; i++) {
2859 if (v[i] != w[i]) {
2860 d++;
2861 }
2862 }
2863 if (d == 1) {
2864 edge(first_pt_idx + h, first_pt_idx + k);
2865 }
2866 }
2867 }
2868
2869
2870 rescale(first_pt_idx, rad_desired);
2871 delete [] Basis;
2872 FREE_int(v);
2873 FREE_int(w);
2874}
2875
2876
2878{
2879 double zero;
2880 double one, minus_one;
2881 double phi, minus_phi;
2882 double phi_inv, minus_phi_inv;
2883
2884 zero = 0.;
2885 one = 1.;
2886 phi = (1. + sqrt(5)) * 0.5;
2887 phi_inv = (sqrt(5) - 1.) * 0.5;
2888 minus_one = -1. * one;
2889 minus_phi = -1. * phi;
2890 minus_phi_inv = -1. * phi_inv;
2891
2892
2893 point(one,one,one); //0
2894 point(one,one,minus_one); //1
2895 point(one,minus_one,one); //2
2896 point(one,minus_one,minus_one); //3
2897 point(minus_one,one,one); //4
2898 point(minus_one,one,minus_one); //5
2899 point(minus_one,minus_one,one); //6
2900 point(minus_one,minus_one,minus_one); //7
2901
2902 point(zero,phi,phi_inv); //8
2903 point(zero,phi,minus_phi_inv); //9
2904 point(zero,minus_phi,phi_inv); //10
2905 point(zero,minus_phi,minus_phi_inv); //11
2906
2907 point(phi_inv,zero,phi); //12
2908 point(phi_inv,zero,minus_phi); //13
2909 point(minus_phi_inv,zero,phi); //14
2910 point(minus_phi_inv,zero,minus_phi); //15
2911
2912 point(phi,phi_inv,zero); //16
2913 point(phi,minus_phi_inv,zero); //17
2914 point(minus_phi,phi_inv,zero); //18
2915 point(minus_phi,minus_phi_inv,zero); //19
2916
2917 // opposite pairs are :
2918 // 0, 7
2919 // 1, 6
2920 // 2, 5
2921 // 3, 4
2922 // 8, 11
2923 // 9, 10
2924 // 12, 15
2925 // 13, 14
2926 // 16, 19
2927 // 17, 18
2928
2929}
2930
2931void scene::Dodecahedron_edges(int first_pt_idx)
2932{
2933 int i, j;
2934 double d;
2935 double phi;
2936 double two_over_phi;
2937
2938 phi = (1. + sqrt(5)) * 0.5;
2939 two_over_phi = 2. / phi;
2940
2941 for (i = 0; i < 20; i++) {
2942 for (j = i + 1; j < 20; j++) {
2944 first_pt_idx + i, first_pt_idx + j);
2945 //cout << "i=" << i << " j=" << j << " d="
2946 //<< d << " two_over_phi=" << two_over_phi;
2947 if (ABS(d - two_over_phi) < 0.2) {
2948 cout << "EDGE " << i << ", " << j << endl;
2949 edge(first_pt_idx + i, first_pt_idx + j);
2950 }
2951 else {
2952 //cout << endl;
2953 }
2954 }
2955 }
2956}
2957
2958void scene::Dodecahedron_planes(int first_pt_idx)
2959{
2960 int i;
2961
2962#if 0
2963 int faces[] = {
2964 8, 9, 11, 10,
2965 12, 14, 15, 13,
2966 16, 17, 19, 18
2967 };
2968 for (i = 0; i < 12; i++) {
2969 faces[i] += first_pt_idx;
2970 }
2971 face(faces + 0, 4);
2972 face(faces + 4, 4);
2973 face(faces + 8, 4);
2974#else
2975 int faces[] = {
2976 0,16,1,9,8,
2977 0,12,2,17,16,
2978 0,8,4,14,12,
2979 1,13,15,5,9,
2980 1,16,17,3,13,
2981 2,10,11,3,17,
2982 2,12,14,6,10,
2983 4,8,9,5,18,
2984 5,15,7,19,18,
2985 6,14,4,18,19,
2986 3,11,7,15,13,
2987 19,7,11,10,6
2988 };
2989 for (i = 0; i < 12 * 5; i++) {
2990 faces[i] += first_pt_idx;
2991 }
2992 for (i = 0; i < 12; i++) {
2993 face(faces + i * 5, 5);
2994 }
2995#endif
2996}
2997
2999{
3000 plane(1/sqrt(3),1/sqrt(3),1/sqrt(3), 3*1/sqrt(3));
3001 plane(1/sqrt(3),1/sqrt(3),1/sqrt(3), 1*1/sqrt(3));
3002 plane(1/sqrt(3),1/sqrt(3),1/sqrt(3), -1*1/sqrt(3));
3003}
3004
3005
3006//##############################################################################
3007// Clebsch cubic, version 1
3008//##############################################################################
3009
3011{
3012 double coeff[20] = {-3,7,7,1,7,-2,-14,7,-14,3,-3,7,1,7,-14,3,-3,1,3,-1.};
3013
3014 cubic(coeff);
3015}
3016
3018{
3019 double t1 = 10;
3020 double t2 = -10;
3021
3022 line(
3023 (-sqrt(5)-3) * t1 + (3*sqrt(5)+7)/2 , t1 , -sqrt(5) * t1 +(sqrt(5)+3)/2 ,
3024 (-sqrt(5)-3) * t2 + (3*sqrt(5)+7)/2 , t2 , -sqrt(5) * t2 +(sqrt(5)+3)/2);
3025 // the line \ell_{0,5} = a_1
3026
3027 line(
3028 -sqrt(5) * t1 +(sqrt(5)+3)/2, (-sqrt(5)-3) * t1 + (3*sqrt(5)+7)/2 , t1 ,
3029 -sqrt(5) * t2 +(sqrt(5)+3)/2, (-sqrt(5)-3) * t2 + (3*sqrt(5)+7)/2 , t2);
3030 // the line \ell_{1,5} = a_2
3031
3032 line(
3033 t1, -sqrt(5) * t1 +(sqrt(5)+3)/2, (-sqrt(5)-3) * t1 + (3*sqrt(5)+7)/2 ,
3034 t2, -sqrt(5) * t2 +(sqrt(5)+3)/2, (-sqrt(5)-3) * t2 + (3*sqrt(5)+7)/2);
3035 // the line \ell_{2,5} = a_3
3036
3037 line(
3038 -(sqrt(5)+3)/4 * t1 + (-sqrt(5)+3)/4 , t1 , (sqrt(5)+1)/4 + (-3*sqrt(5)-5)/4 * t1 ,
3039 -(sqrt(5)+3)/4 * t2 + (-sqrt(5)+3)/4 , t2 , (sqrt(5)+1)/4 + (-3*sqrt(5)-5)/4 * t2);
3040 // the line \ell_{0,7} = a_4
3041
3042 line(
3043 (sqrt(5)+1)/4 + (-3*sqrt(5)-5)/4 * t1, -(sqrt(5)+3)/4 * t1 + (-sqrt(5)+3)/4 , t1 ,
3044 (sqrt(5)+1)/4 + (-3*sqrt(5)-5)/4 * t2, -(sqrt(5)+3)/4 * t2 + (-sqrt(5)+3)/4 , t2);
3045 // the line a_5
3046
3047 line(
3048 t1, (sqrt(5)+1)/4 + (-3*sqrt(5)-5)/4 * t1, -(sqrt(5)+3)/4 * t1 + (-sqrt(5)+3)/4 ,
3049 t2, (sqrt(5)+1)/4 + (-3*sqrt(5)-5)/4 * t2, -(sqrt(5)+3)/4 * t2 + (-sqrt(5)+3)/4);
3050 // the line a_6
3051}
3052
3053
3055{
3056 double t1 = 10;
3057 double t2 = -10;
3058
3059 line(
3060 (sqrt(5)-3) * t1 + (-3*sqrt(5)+7)/2 , t1 , (-sqrt(5)+3)/2 + sqrt(5) * t1 ,
3061 (sqrt(5)-3) * t2 + (-3*sqrt(5)+7)/2 , t2 , (-sqrt(5)+3)/2 + sqrt(5) * t2);
3062 // the line \ell_{0,8} = b_1
3063
3064 line(
3065 (-sqrt(5)+3)/2 + sqrt(5) * t1, (sqrt(5)-3) * t1 + (-3*sqrt(5)+7)/2 , t1 ,
3066 (-sqrt(5)+3)/2 + sqrt(5) * t2, (sqrt(5)-3) * t2 + (-3*sqrt(5)+7)/2 , t2);
3067 // the line \ell_{1,8} = b_2
3068
3069 line(
3070 t1, (-sqrt(5)+3)/2 + sqrt(5) * t1, (sqrt(5)-3) * t1 + (-3*sqrt(5)+7)/2 ,
3071 t2, (-sqrt(5)+3)/2 + sqrt(5) * t2, (sqrt(5)-3) * t2 + (-3*sqrt(5)+7)/2);
3072 // the line \ell_{2,8} = b_2
3073
3074 line(
3075 (sqrt(5)-3)/4 * t1 + (sqrt(5)+3)/4 , t1 , (-sqrt(5)+1)/4 + (3*sqrt(5)-5)/4 * t1 ,
3076 (sqrt(5)-3)/4 * t2 + (sqrt(5)+3)/4 , t2 , (-sqrt(5)+1)/4 + (3*sqrt(5)-5)/4 * t2);
3077 // the line \ell_{0,6} = b_4
3078
3079 line(
3080 (-sqrt(5)+1)/4 + (3*sqrt(5)-5)/4 * t1, (sqrt(5)-3)/4 * t1 + (sqrt(5)+3)/4 , t1 ,
3081 (-sqrt(5)+1)/4 + (3*sqrt(5)-5)/4 * t2, (sqrt(5)-3)/4 * t2 + (sqrt(5)+3)/4 , t2);
3082 // the line \ell_{1,6} = b_5
3083
3084 line(
3085 t1, (-sqrt(5)+1)/4 + (3*sqrt(5)-5)/4 * t1, (sqrt(5)-3)/4 * t1 + (sqrt(5)+3)/4 ,
3086 t2, (-sqrt(5)+1)/4 + (3*sqrt(5)-5)/4 * t2, (sqrt(5)-3)/4 * t2 + (sqrt(5)+3)/4);
3087 // the line \ell_{2,6} = b_6
3088
3089}
3090
3092{
3093 double b = 4.;
3094
3095 // 12 = c_12 3
3096 line(-1. * b, -3. * b - 1, 0., b, 3. * b - 1, 0.);
3097 //cylinder{< -1.*b,-3.*b-1,0. >,<b,3.*b-1,0. > ,r } //c_12
3098 //c_{12} & (t, 3t-1, 0)
3099
3100 // 13 = c_13 4
3101 line(-3. * b -1, 0, -1. * b, 3. * b - 1, 0, b);
3102 //cylinder{< -3.*b-1,0,-1.*b >,<3.*b-1,0,b > ,r } //c_13
3103 //c_{13} & (3t-1, 0,t)
3104
3105 // 14 = c_14 12 bottom
3106 line(b, -1. * b, -1., -1. * b, b, -1.);
3107 //cylinder{< b,-1.*b,-1. >,<-1.*b,b,-1. > ,r } //c_14 bottom plane
3108 //c_{14} & (-t,t,-1)
3109
3110 // 15 = c_15 7 top
3111 line(2. + b, 1, -1. * b, 2. -1. * b, 1, b);
3112 //cylinder{< 2.+b,1,-1.*b >,<2.-1.*b,1,b > ,r } //c_15top plane
3113 //c_{15} & (2-t, 1, t)
3114
3115
3116 // 16 = c_16 15 middle
3117 line(0, b + 1, -1. * b , 0, -1.*b + 1, b);
3118 //cylinder{< 0,b+1,-1.*b >,<0,-1.*b+1,b > ,r } //c_16 middle
3119 //c_{16} & (0, t,1-t)
3120
3121 // 17 = c_23 11
3122 line(0, -1. * b, -3. * b -1., 0, b, 3. * b - 1.);
3123 //cylinder{< 0,-1.*b,-3.*b-1. >,<0,b,3.*b-1. > ,r } //c_23
3124 //c_{23} & (0,t,3t-1)
3125
3126 // 18 = c_24 10 middle
3127 line(b + 1, 0, -1. * b, -1. * b + 1, 0, b);
3128 //cylinder{< b+1,0,-1.*b >,<-1.*b+1,0,b > ,r } //c_24 middle
3129 //c_{24} & (1-t, 0, t)
3130
3131 // 19 = c_25 8 bottom
3132 line(-1, b, -1. * b, -1, -1. * b, b);
3133 //cylinder{< -1,b,-1.*b >,<-1,-1.*b,b > ,r } //c_25 bottom plane
3134 //c_{25} & (-1,t,-t)
3135
3136 // 20 = c_26 6 top
3137 line(2. + b, -1. * b, 1., 2. -1. * b, b, 1.);
3138 //cylinder{< 2.+b,-1.*b,1. >,<2.-1.*b,b,1. > ,r } //c_26 top plane
3139 //c_{26} & (t,2-t,1)
3140
3141 // 21 = c_34 1 top
3142 line(1, 2. + b, -1. * b, 1, 2. -1. * b, b);
3143 //cylinder{< 1,2.+b,-1.*b >,<1,2.-1.*b,b > ,r } //c_34 top plane
3144 //c_{34} & (1, t,2-t)
3145
3146 //22 = c_35 middle
3147 line(b + 1, -1. * b, 0., -1. * b + 1, b, 0.);
3148 //cylinder{< b+1,-1.*b,0. >,<-1.*b+1,b,0. > ,r } //c_35 middle
3149 //c_{35} & (t,1-t,0)
3150
3151 // 23 = c_36 2 bottom
3152 line(b, -1, -1. * b, -1. * b, -1, b);
3153 //cylinder{< b,-1,-1.*b >,<-1.*b,-1,b > ,r } //c_36 bottom plane
3154 //c_{36} & (t,-1,-t)
3155
3156 // 24 = c_45 9
3157 line(0, -3. * b - 1, -1. * b, 0, 3. * b - 1, b);
3158 //cylinder{< 0,-3.*b-1,-1.*b >,<0,3.*b-1,b > ,r } //c_45
3159 //c_{45} & (0, 3t-1, t)
3160
3161 // 25 = c_46 13
3162 line(-3. * b - 1, -1. * b, 0., 3. * b - 1, b, 0.);
3163 //cylinder{< -3.*b-1,-1.*b,0. >,<3.*b-1,b,0. > ,r } //c_46
3164 //c_{46} & (3t-1, t,0)
3165
3166 // 26 = c_56 5
3167 line(-1. * b, 0, -3. * b - 1., b, 0, 3. * b - 1.);
3168 //cylinder{< -1.*b,0,-3.*b-1. >,<b,0,3.*b-1. > ,r } //c_56
3169 //c_{56} & (t,0,3t-1)
3170
3171
3172}
3173
3175{
3176 point(1,1,1. ); //0
3177 point(0,-1,0. ); //1
3178 point(.5,.5,0. ); //2
3179 point(0,.5,.5 ); //3
3180 point(0,0,-1. ); //4
3181 point(.5,0,.5 ); //5
3182 point(-1,0,0. ); //6
3183}
3184
3185//##############################################################################
3186// Clebsch cubic, version 2
3187//##############################################################################
3188
3190{
3191 // this is X0^3+X1^3+X2^3+X3^3-(X0+X1+X2+X3)^3
3192 // = -3*x^2*y - 3*x^2*z - 3*x*y^2 - 6*x*y*z - 3*x*z^2 - 3*y^2*z
3193 // - 3*y*z^2 - 3*x^2 - 6*x*y - 6*x*z - 3*y^2 - 6*y*z - 3*z^2 - 3*x - 3*y - 3*z
3194
3195
3196 double Eqn[20] = {
3197 0, // 1 x^3
3198 -3, // 2 x^2y
3199 -3, // 3 x^2z
3200 -3, // 4 x^2
3201 -3, // 5 xy^2
3202 -6, // 6 xyz
3203 -6, // 7 xy
3204 -3, // 8 xz^2
3205 -6, // 9 xz
3206 -3, // 10 x
3207 0, // 11 y^3
3208 -3, // 12 y^2z
3209 -3, // 13 y^2
3210 -3, // 14 yz^2
3211 -6, // 15 yz
3212 -3, // 16 y
3213 0, // 17 z^3
3214 -3, // 18 z^2
3215 -3, // 19 z
3216 0, // 20 1
3217 };
3218
3219 cubic(Eqn);
3220}
3221
3223{
3224
3225 double Eqn[20] = {
3226 0, // 1 x^3
3227 1, // 2 x^2y
3228 1, // 3 x^2z
3229 0, // 4 x^2
3230 1, // 5 xy^2
3231 2, // 6 xyz
3232 1, // 7 xy
3233 1, // 8 xz^2
3234 1, // 9 xz
3235 0, // 10 x
3236 0, // 11 y^3
3237 1, // 12 y^2z
3238 0, // 13 y^2
3239 1, // 14 yz^2
3240 1, // 15 yz
3241 0, // 16 y
3242 0, // 17 z^3
3243 0, // 18 z^2
3244 0, // 19 z
3245 0, // 20 1
3246 };
3247
3248 cubic(Eqn);
3249}
3250
3251#define scene_alpha ((1. + sqrt(5)) * .5)
3252#define scene_beta ((-1. + sqrt(5)) * .5)
3253
3255{
3256 double A[] = {scene_beta, -1, 0, 1, -1, scene_beta, 1, 0,
3257 scene_beta, -1, 1, -scene_beta, -1, scene_beta, 0, -scene_beta,
3258 scene_beta, -1, -scene_beta, 0, -1, scene_beta, -scene_beta, 1,
3259 -1, -scene_alpha, 0, 1, -scene_alpha, -1, 1, 0,
3261 -1, -scene_alpha, scene_alpha, 0, -scene_alpha, -1, scene_alpha, 1};
3262 int i, j;
3263 double L[8];
3264 double a, av;
3265 numerics N;
3266
3267 for (i = 0; i < 6; i++) {
3268 N.vec_copy(A + i * 8, L, 8);
3269 if (ABS(L[3]) < 0.001 && ABS(L[7]) < 0.001) {
3270 cout << "scene::clebsch_cubic_version2_lines_a line A" << i << " lies at infinity" << endl;
3271 exit(1);
3272 }
3273 if (ABS(L[7]) > ABS(L[3])) {
3274 N.vec_swap(L, L + 4, 4);
3275 }
3276 a = L[3];
3277 av = 1. / a;
3278 N.vec_scalar_multiple(L, av, 4);
3279 a = -L[7];
3280 for (j = 0; j < 4; j++) {
3281 L[4 + j] += L[j] * a;
3282 }
3283 line_extended(L[0], L[1], L[2], L[0] + L[4], L[1] + L[5], L[2] + L[6], 10.);
3284 }
3285}
3286
3288{
3289 double B[] = {-1, -scene_alpha, 1, 0, -scene_alpha, -1, 0, 1,
3292 -1, scene_beta, 0, 1, scene_beta, -1, 1, 0,
3293 -1, scene_beta, 1, -scene_beta, scene_beta, -1, 0, -scene_beta,
3294 -1, scene_beta, -scene_beta, 0, scene_beta, -1, -scene_beta, 1};
3295 int i, j;
3296 double L[8];
3297 double a, av;
3298 numerics N;
3299
3300 for (i = 0; i < 6; i++) {
3301 N.vec_copy(B + i * 8, L, 8);
3302 if (ABS(L[3]) < 0.001 && ABS(L[7]) < 0.001) {
3303 cout << "scene::clebsch_cubic_version2_lines_b line B" << i << " lies at infinity" << endl;
3304 exit(1);
3305 }
3306 if (ABS(L[7]) > ABS(L[3])) {
3307 N.vec_swap(L, L + 4, 4);
3308 }
3309 a = L[3];
3310 av = 1. / a;
3311 N.vec_scalar_multiple(L, av, 4);
3312 a = -L[7];
3313 for (j = 0; j < 4; j++) {
3314 L[4 + j] += L[j] * a;
3315 }
3316 line_extended(L[0], L[1], L[2], L[0] + L[4], L[1] + L[5], L[2] + L[6], 10.);
3317 }
3318
3319}
3320
3322{
3323 double C[] = {
3324 -1,0,0,0,0,-1,0,1,
3325 -1,0,1,0,0,-1,0,0,
3326 1,-1,0,0,0,0,1,-1,
3327 0,0,0,-1,0,1,-1,0,
3328 0,0,1,0,1,0,0,-1,
3329 -1,0,0,1,0,-1,1,0,
3330 0,0,0,-1,1,0,-1,0,
3331 1,-1,0,0,0,0,1,0,
3332
3333 0,0,-1,1,0,1,0,0,
3334 0,0,1,0,0,1,0,-1,
3335 0,0,-1,1,1,0,0,0,
3336 1,-1,0,0,0,0,0,1,
3337 0,-1,0,0,-1,0,0,1,
3338 0,-1,1,0,-1,0,0,0,
3339 0,-1,0,1,-1,0,1,0,
3340 };
3341 int i, j, h;
3342 double L[8];
3343 double a, av;
3344 numerics N;
3345
3346 h = 0;
3347 for (i = 0; i < 15; i++) {
3348 N.vec_copy(C + i * 8, L, 8);
3349 if (ABS(L[3]) < 0.001 && ABS(L[7]) < 0.001) {
3350 cout << "scene::clebsch_cubic_version2_lines_c line C" << i << " lies at infinity" << endl;
3351 continue;
3352 }
3353 if (ABS(L[7]) > ABS(L[3])) {
3354 N.vec_swap(L, L + 4, 4);
3355 }
3356 a = L[3];
3357 av = 1. / a;
3358 N.vec_scalar_multiple(L, av, 4);
3359 a = -L[7];
3360 for (j = 0; j < 4; j++) {
3361 L[4 + j] += L[j] * a;
3362 }
3363 line_extended(L[0], L[1], L[2], L[0] + L[4], L[1] + L[5], L[2] + L[6], 10.);
3364 h++;
3365 }
3366
3367
3368}
3369
3371{
3372 double x1, x2, x3;
3373 double y1, y2, y3;
3374 double d1, d2, d3;
3375 double d;
3376
3377 x1 = Point_coords[pt1 * 3 + 0];
3378 x2 = Point_coords[pt1 * 3 + 1];
3379 x3 = Point_coords[pt1 * 3 + 2];
3380 y1 = Point_coords[pt2 * 3 + 0];
3381 y2 = Point_coords[pt2 * 3 + 1];
3382 y3 = Point_coords[pt2 * 3 + 2];
3383 d1 = y1 - x1;
3384 d2 = y2 - x2;
3385 d3 = y3 - x3;
3386 d = sqrt(d1 * d1 + d2 * d2 + d3 * d3);
3387 return d;
3388}
3389
3391{
3392 plane(0., 0., 1., 0.); // c23'
3393 plane(0., 1., 0., 0.); // c56'
3394 line_extended(0., 0., 0., 0., 1., 0., 5.); // c45'
3395 line_extended(0., 0., 1., 1., 1., 1., 5.); // c46'
3396 line_extended(-sqrt(5) - 3., 2*sqrt(5) + 4., 0.,
3397 0., (sqrt(5) + 1.)/2., (-sqrt(5) + 3.)/2.,
3398 5.); // a2'
3399 line_extended(-4.-2.*sqrt(5), sqrt(5)+3., 0.,
3400 (-sqrt(5)-1.)/2., 1., (sqrt(5)+3.)/2.,
3401 5. ); // a3'
3402}
3403
3404void scene::create_Clebsch_surface(int verbose_level)
3405// 1 cubic, 27 lines, 7 Eckardt points
3406{
3407 int f_v = (verbose_level >= 1);
3408
3409
3410 if (f_v) {
3411 cout << "scene::create_Clebsch_surface" << endl;
3412 }
3413
3414
3415 if (f_v) {
3416 cout << "scene::create_Clebsch_surface creating lines" << endl;
3417 }
3418
3419 clebsch_cubic();
3424
3425#if 0
3426
3427 int i;
3428 double r = sqrt(5);
3429 for (i = 0; i < 27; i++) {
3430
3431 if (f_v) {
3432 cout << "scene::create_Clebsch_surface creating line" << i << endl;
3433 }
3434 line_pt_and_dir_and_copy_points(Hilbert_Cohn_Vossen_Lines + i * 6, r, verbose_level - 1);
3435 }
3436
3437 {
3438 double coeff[20] = {0,0,0,-1,0,5./2.,0,0,0,0,0,0,-1,0,0,0,0,-1,0,1};
3439 cubic(coeff); // cubic 0
3440 }
3441
3442#if 0
3443 for (i = 0; i < 45; i++) {
3444 plane_from_dual_coordinates(Hilbert_Cohn_Vossen_tritangent_planes + i * 4);
3445 }
3446#endif
3447#endif
3448
3449
3450
3451
3452
3453 if (f_v) {
3454 cout << "scene::create_Clebsch_surface done" << endl;
3455 }
3456}
3457
3459// 1 cubic, 27 lines, 54 points, 45 planes
3460{
3461 int f_v = (verbose_level >= 1);
3462
3463
3464 if (f_v) {
3465 cout << "scene::create_Hilbert_Cohn_Vossen_surface" << endl;
3466 }
3467
3468
3469 if (f_v) {
3470 cout << "scene::create_Hilbert_Cohn_Vossen_surface creating lines" << endl;
3471 }
3472
3473 int i;
3474 double r = sqrt(5);
3475 for (i = 0; i < 27; i++) {
3476
3477 if (f_v) {
3478 cout << "scene::create_Hilbert_Cohn_Vossen_surface creating line" << i << endl;
3479 }
3480 line_pt_and_dir_and_copy_points(Hilbert_Cohn_Vossen_Lines + i * 6, r, verbose_level - 1);
3481 }
3482
3483 {
3484 double coeff[20] = {0,0,0,-1,0,5./2.,0,0,0,0,0,0,-1,0,0,0,0,-1,0,1};
3485 cubic(coeff); // cubic 0
3486 }
3487
3488
3489 for (i = 0; i < 45; i++) {
3490 plane_from_dual_coordinates(Hilbert_Cohn_Vossen_tritangent_planes + i * 4);
3491 }
3492
3493
3494
3495
3496
3497 if (f_v) {
3498 cout << "scene::create_Hilbert_Cohn_Vossen_surface done" << endl;
3499 }
3500}
3501
3502
3503void scene::create_Hilbert_model(int verbose_level)
3504{
3505 int f_v = (verbose_level >= 1);
3506
3507
3508 if (f_v) {
3509 cout << "scene::create_Hilbert_model" << endl;
3510 }
3511
3512 verbose_level += 2;
3513
3514 numerics N;
3515 int i;
3516
3517 if (f_v) {
3518 cout << "scene::create_Hilbert_model before create_Hilbert_cube" << endl;
3519 }
3520 create_Hilbert_cube(verbose_level);
3521 if (f_v) {
3522 cout << "scene::create_Hilbert_model after create_Hilbert_cube" << endl;
3523 }
3524
3525#if 0
3526 double p = 1.;
3527 double m = -1.;
3528 double px = p + 1;
3529 double mx = m - 1;
3530 int i;
3531
3532 point(p,p,p); // 0
3533 point(p,p,m); // 1
3534 point(p,m,p); // 2
3535 point(p,m,m); // 3
3536 point(m,p,p); // 4
3537 point(m,p,m); // 5
3538 point(m,m,p); // 6
3539 point(m,m,m); // 7
3540
3541 face4(0, 1, 5, 4); // 0, front right
3542 face4(0, 2, 3, 1); // 1, front left
3543 face4(0, 4, 6, 2); // 2, top
3544 face4(1, 5, 7, 3); // 3, bottom
3545 face4(4, 6, 7, 5); // 4, back right
3546 face4(2, 3, 7, 6); // 5, back left
3547
3548
3549 // top front:
3550 point(px,p,p); // 8
3551 point(p,px,p); // 9
3552 point(p,p,px); // 10
3553
3554 // top back:
3555 point(mx,m,p); // 11
3556 point(m,mx,p); // 12
3557 point(m,m,px); // 13
3558
3559 // bottom left:
3560 point(px,m,m); // 14
3561 point(p,mx,m); // 15
3562 point(p,m,mx); // 16
3563
3564 // bottom right:
3565 point(mx,p,m); // 17
3566 point(m,px,m); // 18
3567 point(m,p,mx); // 19
3568
3569 // the edges of the cube:
3570 edge(0, 1); // 0
3571 edge(0, 2); // 1
3572 edge(0, 4); // 2
3573 edge(1, 3); // 3
3574 edge(1, 5); // 4
3575 edge(2, 3); // 5
3576 edge(2, 6); // 6
3577 edge(3, 7); // 7
3578 edge(4, 5); // 8
3579 edge(4, 6); // 9
3580 edge(5, 7); // 10
3581 edge(6, 7); // 11
3582#endif
3583
3584 if (f_v) {
3585 cout << "scene::create_Hilbert_model creating edges for double six" << endl;
3586 }
3587 // the double six:
3588 // there is a symmetry (a1,a2,a3)(a4,a5,a6)(b1,b2,b3)(b4,b5,b6)
3589 // also, a_i^\perp = b_i
3590 edge(8, 17); // 12 a1
3591 edge(9, 12); // 13 a2
3592 edge(10, 16); // 14 a3
3593 edge(11, 14); // 15 a4
3594 edge(15, 18); // 16 a5
3595 edge(13, 19); // 17 a6
3596
3597 edge(13, 16); // 18 b1
3598 edge(14, 17); // 19 b2
3599 edge(12, 18); // 20 b3
3600 edge(10, 19); // 21 b4
3601 edge(8, 11); // 22 b5
3602 edge(9, 15); // 23 b6
3603
3604
3605 point(2,1,1); // 20
3606 point(-2,1,-1); // 21
3607 point(-6,1,-3); // 22
3608 point(-10,1,-5); // 23
3609
3610 if (f_v) {
3611 cout << "scene::create_Hilbert_model creating the tetrahedron" << endl;
3612 }
3613 // the tetrahedron:
3614 face3(0, 6, 3 ); // 6, left
3615 face3(0, 6, 5 ); // 7, right
3616 face3(0, 3, 5 ); // 8, front
3617 face3(6, 3, 5 ); // 9, back
3618 edge(0, 6); // 24
3619 edge(0, 3); // 25
3620 edge(0, 5); // 26
3621 edge(6, 3); // 27
3622 edge(6, 5); // 28
3623 edge(3, 5); // 29
3624
3625 // the extended edges of the cube:
3626 edge(0, 8); // 30
3627 edge(0, 9); // 31
3628 edge(0, 10); // 32
3629 edge(3, 14); // 33
3630 edge(3, 15); // 34
3631 edge(3, 16); // 35
3632 edge(5, 17); // 36
3633 edge(5, 18); // 37
3634 edge(5, 19); // 38
3635 edge(6, 11); // 39
3636 edge(6, 12); // 40
3637 edge(6, 13); // 41
3638
3639 // the base points in the plane \pi_{12,34,56}
3640 point(4./5., -2./5.,-1.); // 24
3641 point(4./5., -1.,-8./5.); // 25
3642 point(1., -2./5.,-4./5.); // 26
3643 point(8./5., -1.,-4./5.); // 27
3644 point(-2./5., 4./5., -1.); // 28
3645 point(-1., 4./5.,-8./5.); // 29
3646
3647
3648 // the base points in the plane \pi_{16,24,35} (at the bottom)
3649 point(8./5., 1.,4./5.); // 30
3650 point(-4./5., -8./5.,1.); // 31
3651 point(1.,-4./5., -8./5.); // 32
3652 point(-4./5.,-1., 2./5.); // 33
3653 point(2./5.,-4./5.,-1.); // 34
3654 point(1.,2./5.,4./5.); // 35
3655 point(2./5.,-1.,-4./5.); // 36
3656 point(1.,-8./5.,-4./5.); // 37
3657
3658 double planes[] = {
3659 1.,0,0,0, // 0, X=0
3660 0,1.,0,0, // 1, Y=0
3661 0,0,1.,0, // 2, Z=0
3662 -1./2., -1., 1., 1., // 3 a1b2
3663 -2, 1., -1., 1., // 4 a2b1
3664 -5./7., -5./7., 5./7., 1., // 5 pi_{12,34,56}
3665 .5,-1,-1,1, // 6 F1 = \pi_7
3666 2,-1,-1,1, // 7 F2 = \pi_13
3667 0,0,0,1, // 8 F3 = \pi_38 = plane at infinity (cannot draw)
3668 (double)5/(double)4,0,0,1, // 9 G1 = \pi_41
3669 0,-1,0,1, // 10 G2 = \pi_5
3670 0,0,-1,1, // 11 G3 = \pi_15
3671
3672 // tritangent planes in dual coordinates, computed using Maple:
3673
3674 -1, -2, 2, 2, // 12 = start of tritangent planes
3675 -2, 1, -1, 1,
3676 1, -1, -2, 1,
3677 -2, 2, -1, 2,
3678 0, -1, 0, 1,
3679 0, 1, 0, 1,
3680 1, -2, -2, 2,
3681 2, 1, 1, 1,
3682 -1, -1, 2, 1,
3683 2, 2, 1, 2,
3684 2, -1, -2, 2,
3685 -1, -2, 1, 1,
3686 2, -1, -1, 1,
3687 1, 2, 2, 2,
3688 0, 0, -1, 1,
3689 0, 0, 1, 1,
3690 -2, 1, -2, 2,
3691 1, 2, 1, 1,
3692 -2, -2, 1, 2,
3693 1, 1, 2, 1,
3694 -1, 2, -1, 1,
3695 2, 1, 2, 2,
3696 -1, 0, 0, 1,
3697 1, 0, 0, 1,
3698 -1, 2, -2, 2,
3699 -2, -1, 1, 1,
3700 -1, 1, -2, 1,
3701 2, -2, -1, 2,
3702 -2, -1, 2, 2,
3703 1, -2, -1, 1,
3704 -5, -5, 5, 7,
3705 -5, 5, -5, 1,
3706 -5, 0, 0, 4,
3707 5, -5, -5, 1,
3708 0, 0, -5, 4,
3709 -5, 5, -5, 7,
3710 0, -5, 0, 4,
3711 0, 0, 0, 1,
3712 0, 5, 0, 4,
3713 5, -5, -5, 7,
3714 5, 0, 0, 4,
3715 5, 5, 5, 1,
3716 -5, -5, 5, 1,
3717 5, 5, 5, 7,
3718 0, 0, 5, 4
3719 // end of tritangent planes
3720
3721
3722 };
3723 for (i = 0; i < 12 + 45; i++) {
3724 plane_from_dual_coordinates(planes + i * 4);
3725 }
3726
3727
3728
3729 if (f_v) {
3730 cout << "scene::create_Hilbert_model creating lines" << endl;
3731 }
3732
3733 double r = sqrt(5);
3734 for (i = 0; i < 27; i++) {
3735
3736 if (f_v) {
3737 cout << "scene::create_Hilbert_model creating line" << i << endl;
3738 }
3739 line_pt_and_dir(Hilbert_Cohn_Vossen_Lines + i * 6, r, verbose_level - 1);
3740 }
3741
3742 {
3743 double coeff[20] = {0,0,0,-1,0,5./2.,0,0,0,0,0,0,-1,0,0,0,0,-1,0,1};
3744 cubic(coeff); // cubic 0
3745 }
3746 {
3747 // the quadric determined by b2, b3, b4:
3748 double coeff[10] = {-2,-5,5,5,-2,-5,-5,-2,5,7};
3749 quadric(coeff); // quadric 0
3750 }
3751 {
3752 // Cayley's nodal cubic, 6,7,9,15 (starting from 1)
3753 //double a = 0.2;
3754 double coeff_in[20] = {0,0,0,0,0,1,1,0,1,0,0,0,0,0,1,0,0,0,0,0};
3755 double coeff_out[20];
3756 #if 0
3757 for (i = 0; i < 20; i++) {
3758 if (coeff[i]) {
3759 coeff[i] = a;
3760 }
3761 }
3762 #endif
3763 //cubic(coeff);
3764
3765 double A4[] = {
3766 1.,1.,1.,1.,
3767 -1.,-1.,1,1,
3768 1.,-1.,-1.,1,
3769 -1.,1.,-1.,1
3770 };
3771 double A4_inv[16];
3772
3773 N.matrix_double_inverse(A4, A4_inv, 4, 0 /* verbose_level*/);
3774
3775 if (f_v) {
3776 cout << "scene::create_Hilbert_model before substitute_cubic_linear_using_povray_ordering" << endl;
3777 }
3779 coeff_in, coeff_out,
3780 A4_inv, 0 /*verbose_level*/);
3781
3782 if (f_v) {
3783 cout << "i : coeff_in[i] : coeff_out[i]" << endl;
3784 for (i = 0; i < 20; i++) {
3785 cout << i << " : " << coeff_in[i] << " : " << coeff_out[i] << endl;
3786 }
3787 }
3788
3789#if 0
3790 0 : 0 : 0
3791 1 : 0 : 0
3792 2 : 0 : 0
3793 3 : 0 : -0.0625 : x^2
3794 4 : 0 : 0
3795 5 : 1 : 0.125 : xyz
3796 6 : 1 : 0
3797 7 : 0 : 0
3798 8 : 1 : 0
3799 9 : 0 : 0
3800 10 : 0 : 0
3801 11 : 0 : 0
3802 12 : 0 : -0.0625 : y^2
3803 13 : 0 : 0
3804 14 : 1 : 0
3805 15 : 0 : 0
3806 16 : 0 : 0
3807 17 : 0 : -0.0625 : z^2
3808 18 : 0 : 0
3809 19 : 0 : 0.0625 : 1
3810#endif
3811 cubic(coeff_out); // cubic 1
3812
3813 // pts of the tetrahedron: 0,6,3,5
3814 int pts[4] = {0, 6, 3, 5};
3815 double rad = 5.;
3816
3817 if (f_v) {
3818 cout << "scene::create_Hilbert_model lines on Cayley's nodal" << endl;
3819 }
3820 // create lines 27-32 on Cayley's nodal cubic (previously: 15,16,17,18,19,20)
3821 line_through_two_points(pts[0], pts[1], rad);
3822 line_through_two_points(pts[0], pts[2], rad);
3823 line_through_two_points(pts[0], pts[3], rad);
3824 line_through_two_points(pts[1], pts[2], rad);
3825 line_through_two_points(pts[1], pts[3], rad);
3826 line_through_two_points(pts[2], pts[3], rad);
3827#if 0
3828 pts[4];
3829 for (i = 0; i < 4; i++) {
3830 pts[0] = point(A4[0 * 4 + 0], A4[0 * 4 + 1], A4[0 * 4 + 2]);
3831 }
3832#endif
3833
3834 }
3835 clebsch_cubic(); // cubic 2
3836 // lines 33-59 (previously: 21, 21+1, ... 21+26=47)
3840
3841
3842 if (f_v) {
3843 cout << "scene::create_Hilbert_model fermat" << endl;
3844 }
3845 double coeff_fermat[20] = {1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1};
3846 cubic(coeff_fermat); // cubic 3, Fermat
3847 {
3848 double Lines[] = {
3849 -1.,0,0,0,-1.,1, // 60 (previously 48)
3850 0.,-1.,0,-1.,0,1, // 61 (previously 49)
3851 0.,0.,-1.,-1.,1,0 // 62 (previously 50)
3852 };
3853 double r = 3.6; //sqrt(5);
3854 // lines 60-62 (previously 48,49,50)
3855 for (i = 0; i < 3; i++) {
3856 line_pt_and_dir(Lines + i * 6, r, verbose_level - 1);
3857 }
3858 }
3859 // Cayleys ruled surface:
3860 //X0X1X2 − X1^3 − X0^2X3
3861 // XYZ - Y^3 - X^2 coeff (1 based) 6,11,4
3862 double coeff_cayley_ruled[20] =
3863 {0,0,0,-1,0,1,0,0,0,0,-1,0,0,0,0,0,0,0,0,0};
3864 cubic(coeff_cayley_ruled); // cubic 4, Cayley / Chasles ruled
3865
3866 // -x + y - z^3
3867 double coeff_cayley_ruled2[20] =
3868 {0,0,0,0,0,0,0,0,0,-1,0,0,0,0,1,0,-1,0,0,0};
3869 cubic(coeff_cayley_ruled2); // cubic 5, Cayley / Chasles ruled
3870 // xy-x^3-z (-1,1, 1,7, -1,19)
3871 double coeff_cayley_ruled3[20] =
3872 {-1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,-1,0};
3873 cubic(coeff_cayley_ruled3); // cubic 6, Cayley / Chasles ruled
3874
3875
3876 if (f_v) {
3877 cout << "scene::create_Hilbert_model create lines on Cayley's ruled surface" << endl;
3878 }
3879 // create lines on Cayley's ruled surface:
3880 double Line[6];
3881 double s0, s1;
3882 r = 10;
3883 double phi, delta_phi;
3884
3885 int nb_lines0 = nb_lines;
3886 int nb_lines_wanted = 18;
3887 int nb_lines_actual = 0;
3888 delta_phi = M_PI / nb_lines_wanted;
3889 for (i = 0; i < nb_lines_wanted; i++) {
3890 phi = M_PI / 2 + (double) i * delta_phi;
3891 s0 = cos(phi);
3892 s1 = sin(phi);
3893 if (ABS(s0) > 0.01) {
3894 Line[0] = s1 / s0;
3895 Line[1] = Line[0] * Line[0];
3896 Line[2] = 0.;
3897 Line[3] = 0.;
3898 Line[4] = s0;
3899 Line[5] = s1;
3900 if (f_v) {
3901 cout << "creating line " << i << " phi=" << phi << " ";
3902 N.vec_print(Line, 6);
3903 cout << endl;
3904 }
3905 if (line_pt_and_dir(Line, r, verbose_level - 1)) {
3906 nb_lines_actual++;
3907 }
3908 else {
3909 cout << "line could not be created" << endl;
3910 }
3911 }
3912 }
3913 if (f_v) {
3914 cout << "nb_lines0 = " << nb_lines0 << endl;
3915 cout << "nb_lines_actual = " << nb_lines_actual << endl;
3916 cout << "nb_lines = " << nb_lines << endl;
3917 }
3918 point(0,0,0); // 38
3919
3920 if (f_v) {
3921 cout << "scene::create_Hilbert_model create osculating_tangent_line" << endl;
3922 }
3923 double osculating_tangent_line[6] = {0,0,0,1,0,0};
3924 line_pt_and_dir(osculating_tangent_line, r, verbose_level - 1); //
3925
3926 {
3927 // the quadric determined by b1, b2, b3:
3928 double coeff[10] = {2,5,5,5,2,5,5,2,5,3};
3929 quadric(coeff); // quadric 1 B123
3930 }
3931 {
3932 // the quadric determined by b1, b2, b4:
3933 double coeff[10] = {-4,-10,0,0,-4,0,0,1,5,4};
3934 quadric(coeff); // quadric 2 B124
3935 }
3936 {
3937 // the quadric determined by b1, b2, b5:
3938 double coeff[10] = {-2,0,-5,0,8,0,10,-2,0,2};
3939 quadric(coeff); // quadric 3 B125
3940 }
3941 {
3942 // the quadric determined by b1, b2, b6:
3943 double coeff[10] = {-2,-5,-5,-5,-2,5,5,-2,5,7};
3944 quadric(coeff); // quadric 4 B126
3945 }
3946
3947 if (f_v) {
3948 cout << "scene::create_Hilbert_model create coeff_surf_lifted" << endl;
3949 }
3950 {
3951 double coeff_surf_lifted[20] = {0, 0, 0, -4/(double)25,
3952 0, -1, 1, 0, 1, -41/(double)25,
3953 0, 0, -1, 0, -2, 4, 0, -1, 4, -91/(double)25};
3954 //double coeff_surf_lifted[20] = {0, 0, 0, -1, 0, -1, -2, 0, 1, 4, 0, 0,
3955 // -1, 0, 1, 4, 0, (double)-4/(double)25,
3956 // (double)-41/(double)25, (double)-91/(double)25};
3957 cubic(coeff_surf_lifted); // cubic 7, arc_lifting
3958 }
3959 {
3960 double coeff_surf_lifted[20] = {0, 0, 0, (double)-1/(double)4, 0,
3961 (double)-5/(double)4, 0, 0, 0, (double)-6/(double)5,
3962 0, 0, -1, 0, -3, 0, 0, -1, 0, (double)-11/(double)25};
3963 cubic(coeff_surf_lifted); // cubic 8, arc_lifting
3964 }
3965
3966 if (f_v) {
3967 cout << "scene::create_Hilbert_model create long lines" << endl;
3968 }
3969
3970
3971 // the lines in long:
3972 cout << "the long lines start at " << nb_lines << endl;
3973 r = 3.6;
3974 for (i = 0; i < 27; i++) {
3975 line_pt_and_dir(Hilbert_Cohn_Vossen_Lines + i * 6, r, verbose_level - 1);
3976 }
3977
3978
3979 point(1,0,0); // P39
3980 point(0,1,0); // P40
3981 point(0,0,1); // P41
3982 edge(38,39); // E42
3983 edge(38,40); // E42
3984 edge(38,41); // E42
3985
3986 if (f_v) {
3987 cout << "scene::create_Hilbert_model done" << endl;
3988 }
3989}
3990
3992{
3993 int f_v = (verbose_level >= 1);
3994 numerics Num;
3995 int idx;
3996
3997 if (f_v) {
3998 cout << "scene::create_Cayleys_nodal_cubic" << endl;
3999 }
4000
4001 // Cayley's nodal cubic, 6,7,9,15 (starting from 1)
4002 {
4003 //double a = 0.2;
4004 double coeff_in[20] = {0,0,0,0,0,1,1,0,1,0,0,0,0,0,1,0,0,0,0,0};
4005 double coeff_out[20];
4006#if 0
4007 for (i = 0; i < 20; i++) {
4008 if (coeff[i]) {
4009 coeff[i] = a;
4010 }
4011 }
4012#endif
4013 //cubic(coeff);
4014
4015 double A4[] = {
4016 1.,1.,1.,1.,
4017 -1.,-1.,1,1,
4018 1.,-1.,-1.,1,
4019 -1.,1.,-1.,1
4020 };
4021 double A4_inv[16];
4022
4023 Num.matrix_double_inverse(A4, A4_inv, 4, 0 /* verbose_level*/);
4024
4026 coeff_in, coeff_out,
4027 A4_inv, 0 /*verbose_level*/);
4028
4029 if (f_v) {
4030 int i;
4031
4032 cout << "i : coeff_in[i] : coeff_out[i]" << endl;
4033 for (i = 0; i < 20; i++) {
4034 cout << i << " : " << coeff_in[i] << " : " << coeff_out[i] << endl;
4035 }
4036 }
4037
4038#if 0
40390 : 0 : 0
40401 : 0 : 0
40412 : 0 : 0
40423 : 0 : -0.0625 : x^2
40434 : 0 : 0
40445 : 1 : 0.125 : xyz
40456 : 1 : 0
40467 : 0 : 0
40478 : 1 : 0
40489 : 0 : 0
404910 : 0 : 0
405011 : 0 : 0
405112 : 0 : -0.0625 : y^2
405213 : 0 : 0
405314 : 1 : 0
405415 : 0 : 0
405516 : 0 : 0
405617 : 0 : -0.0625 : z^2
405718 : 0 : 0
405819 : 0 : 0.0625 : 1
4059#endif
4060 idx = cubic(coeff_out); // cubic 1
4061 cout << "created cubic " << idx << endl;
4062
4063 // pts of the tetrahedron: 0,6,3,5
4064 int pts[4] = {0, 6, 3, 5};
4065 double rad = 5.;
4066
4067
4068 // create lines 27-32 on Cayley's nodal cubic (previously: 15,16,17,18,19,20)
4069 idx = line_through_two_points(pts[0], pts[1], rad); // line 27
4070 cout << "created line " << idx << endl;
4071 idx = line_through_two_points(pts[0], pts[2], rad);
4072 cout << "created line " << idx << endl;
4073 idx = line_through_two_points(pts[0], pts[3], rad);
4074 cout << "created line " << idx << endl;
4075 idx = line_through_two_points(pts[1], pts[2], rad);
4076 cout << "created line " << idx << endl;
4077 idx = line_through_two_points(pts[1], pts[3], rad);
4078 cout << "created line " << idx << endl;
4079 idx = line_through_two_points(pts[2], pts[3], rad);
4080 cout << "created line " << idx << endl;
4081
4082#if 0
4083 pts[4];
4084 for (i = 0; i < 4; i++) {
4085 pts[0] = point(A4[0 * 4 + 0], A4[0 * 4 + 1], A4[0 * 4 + 2]);
4086 }
4087#endif
4088
4089 }
4090
4091 if (f_v) {
4092 cout << "scene::create_Cayleys_nodal_cubic done" << endl;
4093 }
4094}
4095
4096void scene::create_Hilbert_cube(int verbose_level)
4097{
4098 int f_v = (verbose_level >= 1);
4099
4100
4101 if (f_v) {
4102 cout << "scene::create_Hilbert_cube" << endl;
4103 }
4104 numerics N;
4105 double p = 1.;
4106 double m = -1.;
4107 double px = p + 1;
4108 double mx = m - 1;
4109
4110
4111 if (f_v) {
4112 cout << "scene::create_Hilbert_cube before create_cube" << endl;
4113 }
4114 create_cube(verbose_level);
4115 if (f_v) {
4116 cout << "scene::create_Hilbert_cube after create_cube" << endl;
4117 }
4118
4119#if 0
4120 point(p,p,p); // 0
4121 point(p,p,m); // 1
4122 point(p,m,p); // 2
4123 point(p,m,m); // 3
4124 point(m,p,p); // 4
4125 point(m,p,m); // 5
4126 point(m,m,p); // 6
4127 point(m,m,m); // 7
4128
4129 face4(0, 1, 5, 4); // 0, front right
4130 face4(0, 2, 3, 1); // 1, front left
4131 face4(0, 4, 6, 2); // 2, top
4132 face4(1, 5, 7, 3); // 3, bottom
4133 face4(4, 6, 7, 5); // 4, back right
4134 face4(2, 3, 7, 6); // 5, back left
4135#endif
4136
4137 // top front:
4138 point(px,p,p); // 8
4139 point(p,px,p); // 9
4140 point(p,p,px); // 10
4141
4142 // top back:
4143 point(mx,m,p); // 11
4144 point(m,mx,p); // 12
4145 point(m,m,px); // 13
4146
4147 // bottom left:
4148 point(px,m,m); // 14
4149 point(p,mx,m); // 15
4150 point(p,m,mx); // 16
4151
4152 // bottom right:
4153 point(mx,p,m); // 17
4154 point(m,px,m); // 18
4155 point(m,p,mx); // 19
4156
4157 // the edges of the cube:
4158 edge(0, 1); // 0
4159 edge(0, 2); // 1
4160 edge(0, 4); // 2
4161 edge(1, 3); // 3
4162 edge(1, 5); // 4
4163 edge(2, 3); // 5
4164 edge(2, 6); // 6
4165 edge(3, 7); // 7
4166 edge(4, 5); // 8
4167 edge(4, 6); // 9
4168 edge(5, 7); // 10
4169 edge(6, 7); // 11
4170 if (f_v) {
4171 cout << "scene::create_Hilbert_cube done" << endl;
4172 }
4173}
4174
4175void scene::create_cube(int verbose_level)
4176{
4177 int f_v = (verbose_level >= 1);
4178
4179
4180 if (f_v) {
4181 cout << "scene::create_cube" << endl;
4182 }
4183 numerics N;
4184 double p = 1.;
4185 double m = -1.;
4186
4187 point(p,p,p); // 0
4188 point(p,p,m); // 1
4189 point(p,m,p); // 2
4190 point(p,m,m); // 3
4191 point(m,p,p); // 4
4192 point(m,p,m); // 5
4193 point(m,m,p); // 6
4194 point(m,m,m); // 7
4195
4196 face4(0, 1, 5, 4); // 0, front right
4197 face4(0, 2, 3, 1); // 1, front left
4198 face4(0, 4, 6, 2); // 2, top
4199 face4(1, 5, 7, 3); // 3, bottom
4200 face4(4, 6, 7, 5); // 4, back right
4201 face4(2, 3, 7, 6); // 5, back left
4202
4203
4204 if (f_v) {
4205 cout << "scene::create_cube done" << endl;
4206 }
4207}
4208
4210{
4211 int f_v = (verbose_level >= 1);
4212
4213
4214 if (f_v) {
4215 cout << "scene::create_cube_and_tetrahedra" << endl;
4216 }
4217
4218 create_cube(verbose_level);
4219
4220 int i, j;
4221
4222 for (i = 0; i < 8; i++) {
4223 for (j = i + 1; j < 8; j++) {
4224 edge(i, j); // 0
4225 }
4226 }
4227
4228
4229
4230 // create faces:
4231
4233
4234 int set[3];
4235 int nCk = Combi.int_n_choose_k(8, 3);
4236 int rk;
4237 int first_three_face;
4238
4239 first_three_face = nb_faces; // = 6, because create_cube creates six faces for the cube
4240 if (f_v) {
4241 cout << "first_three_face = " << first_three_face << endl;
4242 }
4243 for (rk = 0; rk < nCk; rk++) {
4244 Combi.unrank_k_subset(rk, set, 8 /*n*/, 3 /*k*/);
4245 face3(set[0], set[1], set[2]);
4246 if (f_v) {
4247 cout << "rk=" << rk << " set=";
4248 Int_vec_print(cout, set, 3);
4249 cout << endl;
4250 }
4251 }
4252
4253 if (f_v) {
4254 cout << "scene::create_cube_and_tetrahedra done" << endl;
4255 }
4256}
4257
4258void scene::create_affine_space(int q, int verbose_level)
4259{
4260 int f_v = (verbose_level >= 1);
4261
4262
4263 if (f_v) {
4264 cout << "scene::create_affine_space" << endl;
4265 }
4266 numerics N;
4267 int x, y, z;
4268 double half = 3.6 / sqrt(3);
4269 double dx = 2 * half / (double) q;
4270 double dx_half = dx * 0.5;
4271 //double center[3];
4272 double basis[9];
4273 double v[3];
4274
4275 basis[0] = sqrt(6) / 3.;
4276 basis[1] = -1 * sqrt(6) / 6.;
4277 basis[2] = -1 * sqrt(6) / 6.;
4278 basis[3] = 0.;
4279 basis[4] = sqrt(2) * 0.5;
4280 basis[5] = -1 * sqrt(2) * 0.5;
4281 basis[6] = -7./15.;
4282 basis[7] = -7./15.;
4283 basis[8] = -7./15.;
4284
4285
4286 cout << "dx = " << dx << endl;
4287 cout << "dx_half = " << dx_half << endl;
4288 //center[0] = -half;
4289 //center[1] = -half;
4290 //center[2] = -half;
4291
4293 affine_space_q = 0;
4295
4296 cout << "start_point for affine space over F_" << q
4297 << "=" << affine_space_starting_point << endl;
4298
4299 for (x = 0; x < q; x++) {
4300 for (y = 0; y < q; y++) {
4301 for (z = 0; z < q; z++) {
4303 -half + x * dx + dx_half, basis + 0,
4304 -half + y * dx + dx_half, basis + 3,
4305 -half + z * dx + dx_half, basis + 6,
4306 v, 3);
4307
4308 point(v[0], v[1], v[2]);
4309 }
4310 }
4311 }
4312
4313 if (f_v) {
4314 cout << "scene::create_affine_space done" << endl;
4315 }
4316}
4317
4318
4319void scene::create_Eckardt_surface(int N, int verbose_level)
4320{
4321 int f_v = (verbose_level >= 1);
4322 int i;
4323
4324 if (f_v) {
4325 cout << "scene::create_Eckardt_surface" << endl;
4326 }
4327
4328 //double coeff_in[20] = {0,3,3,5,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1};
4329 // by accident, this is the wrong ordering of coefficients!
4330 // it is the ordering of coefficients in orbiter.
4331 // But it should be the ordering of coefficients required by povray.
4332
4333
4334 double coeff_orig[20] = {0,0,0,-1,0,2.5,0,0,0,0,0,0,-1,0,0,0,0,-1,0,1};
4335 // HCV original
4336 // 4: -1*x^2
4337 // 6: 2.5*xyz
4338 // 13: -1*y^2
4339 // 18: -1*z^2
4340 // 20: 1*1
4341
4342
4343 // povray ordering of monomials:
4344 // http://www.povray.org/documentation/view/3.6.1/298/
4345 // 1: x^3
4346 // 2: x^2y
4347 // 3: x^2z
4348 // 4: x^2
4349 // 5: xy^2
4350 // 6: xyz
4351 // 7: xy
4352 // 8: xz^2
4353 // 9: xz
4354 // 10: x
4355 // 11: y^3
4356 // 12: y^2z
4357 // 13: y^2
4358 // 14: yz^2
4359 // 15: yz
4360 // 16: y
4361 // 17: z^3
4362 // 18: z^2
4363 // 19: z
4364 // 20: 1
4365
4366 double coeff_trans[20] = {1,0,0,0,-1,0,0,-1,0,-1,0,0,0,0,2.5,0,0,0,0,0};
4367 // HCV original
4368
4369 double coeff_out[20];
4370
4371
4372
4373 cubic(coeff_orig); // cubic 0
4374 cubic(coeff_trans); // cubic 1
4375
4376 numerics Num;
4377
4378 double A4[] = {
4379 1.,1.,1.,1.,
4380 -1.,-1.,1,1,
4381 1.,-1.,-1.,1,
4382 -1.,1.,-1.,1
4383 };
4384 double A4_inv[16];
4385
4386 Num.matrix_double_inverse(A4, A4_inv, 4, 0 /* verbose_level*/);
4387
4389 coeff_orig, coeff_out,
4390 A4_inv, 0 /*verbose_level*/);
4391
4392
4393
4394 if (f_v) {
4395 cout << "i : coeff_orig[i] : coeff_out[i]" << endl;
4396 for (i = 0; i < 20; i++) {
4397 cout << i << " : " << coeff_orig[i] << " : " << coeff_out[i] << endl;
4398 }
4399 }
4400
4401#if 0
44020 : 0 : 0
44031 : 0 : 0
44042 : 0 : 0
44053 : 0 : -0.0625 : x^2
44064 : 0 : 0
44075 : 1 : 0.125 : xyz
44086 : 1 : 0
44097 : 0 : 0
44108 : 1 : 0
44119 : 0 : 0
441210 : 0 : 0
441311 : 0 : 0
441412 : 0 : -0.0625 : y^2
441513 : 0 : 0
441614 : 1 : 0
441715 : 0 : 0
441816 : 0 : 0
441917 : 0 : -0.0625 : z^2
442018 : 0 : 0
442119 : 0 : 0.0625 : 1
4422#endif
4423 cubic(coeff_out); // cubic 2
4424
4425 double sqrt3 = sqrt(3.);
4426 double one_over_sqrt3 = 1. / sqrt3;
4427
4428 plane(-1 * one_over_sqrt3, one_over_sqrt3, -1 * one_over_sqrt3, -1 * one_over_sqrt3); // plane 0
4429
4430
4431#if 0
4432 double lines[] = {
4433 1,1,1,0,1,1,
4434 1,1,1,1,1,0,
4435 -1,-1,1,-1,0,1,
4436 };
4437 int k;
4438
4439 k = 0;
4440 for (i = 0; i < 3; i++) {
4441 k = 6 * i;
4442 S->line_extended(
4443 lines[k + 0], lines[k + 1], lines[k + 2],
4444 lines[k + 0] + lines[k + 3], lines[k + 1] + lines[k + 4], lines[k + 2] + lines[k + 5], 10); // line i
4445 }
4446#endif
4447
4448#if 0
4449 // the lines on the original HCV surface:
4450 double Lines[] = {
4451 0,1,0,-2,0,-1, // 0 a1
4452 0,0,1,-1,-2,0, // 1 a2
4453 1,0,0,0,-1,-2, // 2 a3
4454 0,-1,0,2,0,-1, // 3 a4
4455 0,0,-1,-1,2,0, // 4 a5
4456 -1,0,0,0,1,-2, // 5 a6
4457 0,-1,0,1,0,-2, // 6 b1
4458 0,0,-1,-2,1,0, // 7 b2
4459 -1,0,0,0,2,-1, // 8 b3
4460 0,1,0,-1,0,-2, // 9 b4
4461 0,0,1,-2,-1,0, // 10 b5
4462 1,0,0,0,-2,-1, // 11 b6
4463 4./5., 3./5., 0, 0., 1., 1., // 12, 0, c12
4464 3./5., 0., 4./5., 1, 1., 0., // 13, 1, c13
4465 0.,0.,1., 1.,0.,0., // 14, 2 c14 at infinity
4466 -4./5., 3./5., 0., 0., -1., 1., // 15, 3 c15
4467 -3./5., 0., -4./5., -1., 1., 0., // 16, 4 c16
4468 -3./5., 4./5., 0., 1., 0., 1., // 17, 5 c23
4469 -4./5., -3./5., 0., 0., -1., 1., // 18, 6 c24
4470 0., 1., 0., 1., 0., 0., // 19, 7 c25 at infinity
4471 3./5., -4./5., 0., -1., 0., 1., // 20, 8 c26
4472 3./5., 0., -4./5., -1., 1., 0., // 21, 9 c34
4473 -3./5., -4./5., 0., -1., 0., 1., // 22, 10 c35
4474 0., 0., 1., 0., 1., 0., // 23, 11 c36 at infinity
4475 4./5., -3./5., 0., 0., 1., 1., // 24, 12 c45
4476 -3./5., 0., 4./5., 1., 1., 0., // 25, 13 c46
4477 3./5., 4./5., 0., 1., 0., 1., // 26, 14 c56
4478 };
4479
4480 double *Lines4_in;
4481 double *Lines4_out;
4482
4483 double T[] = {
4484 1,1,1,1,
4485 -1,-1,1,1,
4486 1,-1,-1,1,
4487 -1,1,-1,1
4488 };
4489
4490
4491 Lines4_in = new double[27 * 2 * 4];
4492 Lines4_out = new double[27 * 2 * 4];
4493 for (i = 0; i < 27; i++) {
4494 for (j = 0; j < 3; j++) {
4495 Lines4_in[i * 8 + j] = Lines[6 * i + j];
4496 Lines4_in[i * 8 + 4 + j] = Lines[6 * i + 3 + j];
4497 }
4498 if (i == 14 || i == 19 || i == 23) {
4499 Lines4_in[i * 8 + 3] = 0;
4500 Lines4_in[i * 8 + 4 + 3] = 0;
4501 }
4502 else {
4503 Lines4_in[i * 8 + 3] = 1;
4504 Lines4_in[i * 8 + 4 + 3] = 0;
4505 }
4506 }
4508 Lines4_in, T, Lines4_out, 2 * 27, 4, 4);
4509 // A is m x n, B is n x o, C is m x o
4510#endif
4511
4512 double Lines[] = {
4513 // 0-5:
4514 // ai:
4515 -1,0,0,6,1,1,
4516 -1./6.,-1./6.,0,-1./6.,-1./6.,1,
4517 0,1,0,-1,6,1,
4518 1,6,0,0,-1,1,
4519 -6,0,1,-1,1,0,
4520 6,-1,0,1,0,1,
4521 // 6-11:
4522 // bj:
4523 1,-6,0,0,-1,1,
4524 6,0,1,-1,1,0,
4525 -6,-1,0,1,0,1,
4526 -1,0,0,-6,1,1,
4527 1./6.,1./6.,0,1./6.,1./6.,1,
4528 0,1,0,-1,-6,1,
4529 //12-26
4530 // cij:
4531 0,-1,0,-2,9,1,
4532 1./9.,2./9.,0,-1./9.,-2./9.,1,
4533 1,0,0,0,1,1,
4534 -9./2.,-1./2.,0,-1,0,1,
4535 9,0,2,1,1,0,
4536 1,0,0,9./2.,1./2.,1,
4537 9,-2,0,-1,0,1,
4538 0,0,1,1,1,0,
4539 1./2.,9./2.,0,0,1,1,
4540 -9./2.,0,1./2.,1,1,0,
4541 2.,-9.,0,0,1,1,
4542 0,-1,0,-1,0,1,
4543 0,-1,0,-1./2.,-9./2.,1,
4544 -2./9.,-1./9.,0,2./9.,1./9.,1,
4545 1,0,0,-9,2,1
4546 };
4547 double r = 10;
4548 for (i = 0; i < 27; i++) {
4549 line_pt_and_dir(Lines + i * 6, r, verbose_level - 1);
4550 }
4551
4552 //S->line6(lines); // line 0
4553 //S->line6(lines + 6); // line 0
4554 //S->line6(lines + 12); // line 0
4555
4556 point(0,-1,0); // 0 = Eckardt point
4557 point(1,0,0); // 1 = Eckardt point
4558 point(0,0,1); // 2 = Eckardt point
4559
4560
4561 if (f_v) {
4562 cout << "scene::create_Eckardt_surface done" << endl;
4563 }
4564}
4565
4566void scene::create_E4_surface(int N, int verbose_level)
4567{
4568 int f_v = (verbose_level >= 1);
4569
4570 if (f_v) {
4571 cout << "scene::create_E4_surface" << endl;
4572 }
4573
4574 //double coeff_in[20] = {0,3,3,5,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1};
4575 // by accident, this is the wrong ordering of coefficients!
4576 // it is the ordering of coefficients in orbiter.
4577 // But it should be the ordering of coefficients required by povray.
4578
4579 //double coeff_in[20] = {5,3,3,0,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,0};
4580 // transformed, but still wrong ordering
4581
4582 double coeff_orig[20] = {0,0,0,2,0,0,0,0,0,0,3,0,0,0,1,0,3,0,0,5};
4583 // original, correct ordering.
4584
4585 double coeff_trans[20] = {5,0,0,0,0,1,0,0,0,2,3,0,0,0,0,0,3,0,0,0};
4586 // transformed, correct ordering.
4587
4588
4589 cubic(coeff_orig);
4590 cubic(coeff_trans);
4591
4592 double x6[6];
4593 int line_idx;
4594
4595 x6[0] = 0;
4596 x6[1] = 4;
4597 x6[2] = -4;
4598 x6[3] = 0;
4599 x6[4] = -4;
4600 x6[5] = 4;
4601
4602 line_idx = line6(x6);
4603 cout << "line_idx=" << line_idx << endl;
4604
4605
4606 if (f_v) {
4607 cout << "scene::create_E4_surface done" << endl;
4608 }
4609}
4610
4611void scene::create_twisted_cubic(int N, int verbose_level)
4612{
4613 //int f_v = (verbose_level >= 1);
4614 numerics Num;
4615 int i;
4616 double t, x, y, z;
4617
4618 if (TRUE) {
4619 cout << "scene::create_twisted_cubic" << endl;
4620 }
4621
4622
4623 double p = 1.;
4624 double m = 0.;
4625
4626 point(p,p,p); // 0
4627 point(p,p,m); // 1
4628 point(p,m,p); // 2
4629 point(p,m,m); // 3
4630 point(m,p,p); // 4
4631 point(m,p,m); // 5
4632 point(m,m,p); // 6
4633 point(m,m,m); // 7
4634
4635
4636 // the edges of the cube:
4637 edge(0, 1); // 0
4638 edge(0, 2); // 1
4639 edge(0, 4); // 2
4640 edge(1, 3); // 3
4641 edge(1, 5); // 4
4642 edge(2, 3); // 5
4643 edge(2, 6); // 6
4644 edge(3, 7); // 7
4645 edge(4, 5); // 8
4646 edge(4, 6); // 9
4647 edge(5, 7); // 10
4648 edge(6, 7); // 11
4649
4650
4651
4652 for (i = 0; i < N; i++) {
4653 t = i * 1. / (double) (N - 1);
4654 x = t;
4655 y = t * t;
4656 z = y * t;
4657 point(x, y, z); // P_8+i
4658 if (i) {
4659 edge(8 + i, 8 + i - 1); // E_i-1
4660
4661 }
4662 }
4663
4664}
4665
4666void scene::create_triangulation_of_cube(int N, int verbose_level)
4667{
4668 int f_v = (verbose_level >= 1);
4669 numerics Num;
4670
4671 if (f_v) {
4672 cout << "scene::create_triangulation_of_cube" << endl;
4673 }
4674
4675
4676 double p = 1.;
4677 double m = -1.;
4678
4679 point(p,p,p); // 0
4680 point(p,p,m); // 1
4681 point(p,m,p); // 2
4682 point(p,m,m); // 3
4683 point(m,p,p); // 4
4684 point(m,p,m); // 5
4685 point(m,m,p); // 6
4686 point(m,m,m); // 7
4687
4688
4689 // the edges of the cube:
4690 edge(0, 1); // 0
4691 edge(0, 2); // 1
4692 edge(0, 4); // 2
4693 edge(1, 3); // 3
4694 edge(1, 5); // 4
4695 edge(2, 3); // 5
4696 edge(2, 6); // 6
4697 edge(3, 7); // 7
4698 edge(4, 5); // 8
4699 edge(4, 6); // 9
4700 edge(5, 7); // 10
4701 edge(6, 7); // 11
4702
4703
4704 face4(0, 1, 5, 4); // F0, front right
4705 face4(0, 2, 3, 1); // F1, front left
4706 face4(0, 4, 6, 2); // F2, top
4707 face4(1, 5, 7, 3); // F3, bottom
4708 face4(4, 6, 7, 5); // F4, back right
4709 face4(2, 3, 7, 6); // F5, back left
4710
4711
4712 face3(0, 3, 5); // F6
4713 face3(0, 3, 6); // F7
4714 face3(0, 5, 6); // F8
4715 face3(3, 5, 6); // F9
4716
4717 edge(0, 3); // E12
4718 edge(0, 5); // E13
4719 edge(0, 6); // E14
4720 edge(3, 5); // E15
4721 edge(3, 6); // E16
4722 edge(5, 6); // E17
4723
4724}
4725
4726void scene::print_a_line(int line_idx)
4727{
4728 numerics Num;
4729
4730 cout << "Line " << line_idx << " is ";
4731 Num.vec_print(Line_coords + line_idx * 6 + 0, 3);
4732 cout << " - ";
4733 Num.vec_print(Line_coords + line_idx * 6 + 3, 3);
4734 cout << endl;
4735}
4736
4737
4738void scene::print_a_plane(int plane_idx)
4739{
4740 numerics Num;
4741
4742 cout << "Plane " << plane_idx << " : ";
4743 Num.vec_print(Plane_coords + plane_idx * 4, 4);
4744 cout << endl;
4745}
4746
4747void scene::print_a_face(int face_idx)
4748{
4749 cout << "face " << face_idx << " has " << Nb_face_points[face_idx] << " points: ";
4750 Int_vec_print(cout, Face_points[face_idx], Nb_face_points[face_idx]);
4751 cout << endl;
4752
4753}
4754
4755#define MY_OWN_BUFSIZE ONE_MILLION
4756
4757void scene::read_obj_file(std::string &fname, int verbose_level)
4758{
4759 int f_v = (verbose_level >= 1);
4760 char *buf;
4761 char *p_buf;
4762 double x, y, z;
4763 double x0, y0, z0;
4764 double x1, y1, z1;
4765 double sx = 0, sy = 0, sz = 0;
4766 int line_nb = -1;
4767 char str[1000];
4768 int a, l, h;
4769 int *w;
4770 int nb_points0;
4771 int nb_pts = 0;
4772 int nb_faces_read = 0;
4773 int idx, pt_idx;
4774
4775 if (f_v) {
4776 cout << "scene::read_obj_file" << endl;
4777 }
4778
4779 buf = NEW_char(MY_OWN_BUFSIZE);
4780
4781 nb_points0 = nb_points;
4782
4783
4784 {
4785 ifstream fp(fname);
4787
4788
4789 while (TRUE) {
4790 if (fp.eof()) {
4791 break;
4792 }
4793 line_nb++;
4794 fp.getline(buf, MY_OWN_BUFSIZE, '\n');
4795 //cout << "read line " << line << " : '" << buf << "'" << endl;
4796 if (strlen(buf) == 0) {
4797 //cout << "scene::read_obj_file empty line, skipping" << endl;
4798 continue;
4799 }
4800
4801 if (strncmp(buf, "#", 1) == 0) {
4802 continue;
4803 }
4804 else if (strncmp(buf, "v ", 2) == 0) {
4805 p_buf = buf + 2;
4806 ST.s_scan_double(&p_buf, &x);
4807 ST.s_scan_double(&p_buf, &y);
4808 ST.s_scan_double(&p_buf, &z);
4809 if (nb_pts == 0) {
4810 x0 = x;
4811 x1 = x;
4812 y0 = y;
4813 y1 = y;
4814 z0 = z;
4815 z1 = z;
4816 }
4817 else {
4818 x0 = min(x0, x);
4819 x1 = max(x1, x);
4820 y0 = min(y0, y);
4821 y1 = max(y1, y);
4822 z0 = min(z0, z);
4823 z1 = max(z1, z);
4824 }
4825 if (ABS(x) > ONE_MILLION) {
4826 cout << "x coordinate out of range, skipping: " << x << endl;
4827 cout << "read line " << line_nb << " : '" << buf << "'" << endl;
4828 continue;
4829 }
4830 if (ABS(y) > ONE_MILLION) {
4831 cout << "y coordinate out of range, skipping: " << y << endl;
4832 cout << "read line " << line_nb << " : '" << buf << "'" << endl;
4833 continue;
4834 }
4835 if (ABS(z) > ONE_MILLION) {
4836 cout << "z coordinate out of range, skipping: " << z << endl;
4837 cout << "read line " << line_nb << " : '" << buf << "'" << endl;
4838 continue;
4839 }
4840 sx += x;
4841 sy += y;
4842 sz += z;
4843 nb_pts++;
4844 //cout << "point : " << x << "," << y << "," << z << endl;
4845 point(x, y, z);
4846 }
4847 else if (strncmp(buf, "f ", 2) == 0) {
4848
4849 nb_faces_read++;
4850 //cout << "reading face: " << buf << endl;
4851 p_buf = buf + 2;
4852 vector<int> v;
4853 while (strlen(p_buf)) {
4854 ST.s_scan_token_arbitrary(&p_buf, str);
4855 //cout << "read token: " << str << endl;
4856 if (strlen(str) == 0) {
4857 continue;
4858 }
4859 l = strlen(str);
4860 for (h = 0; h < l; h++) {
4861 if (str[h] == '/') {
4862 str[h] = 0;
4863 a = atoi(str);
4864 break;
4865 }
4866 }
4867 if (h == l) {
4868 a = atoi(str);
4869 }
4870 //cout << "reading it as " << a << endl;
4871 v.push_back(a);
4872 }
4873 l = v.size();
4874 w = NEW_int(l + 1);
4875 for (h = 0; h < l; h++) {
4876 w[h] = v[h] - 1 + nb_points0;
4877 }
4878 if (w[l - 1] != w[0]) {
4879 w[l] = w[0];
4880 l++;
4881 }
4882 //cout << "read face : ";
4883 //int_vec_print(cout, w, l);
4884 //cout << endl;
4885 idx = face(w, l);
4886 if (FALSE && idx == 2920) {
4887 cout << "added face " << idx << ": ";
4888 Int_vec_print(cout, w, l);
4889 cout << endl;
4890 for (h = 0; h < l; h++) {
4891 pt_idx = w[h];
4892 double x, y, z;
4893 x = point_coords(pt_idx, 0);
4894 y = point_coords(pt_idx, 0);
4895 z = point_coords(pt_idx, 0);
4896 cout << "Point " << pt_idx << " : x="
4897 << x << " y=" << y << " z=" << z << endl;
4898 }
4899 }
4900 FREE_int(w);
4901 }
4902 }
4903 cout << "midpoint: " << sx / nb_pts << ", " << sy / nb_pts << ", " << sz / nb_pts << endl;
4904 cout << "x-interval: [" << x0 << ", " << x1 << "]" << endl;
4905 cout << "y-interval: [" << y0 << ", " << y1 << "]" << endl;
4906 cout << "z-interval: [" << z0 << ", " << z1 << "]" << endl;
4907 cout << "number points read: " << nb_pts << endl;
4908 cout << "number faces read: " << nb_faces_read << endl;
4909 }
4910 if (f_v) {
4911 cout << "scene::read_obj_file done" << endl;
4912 }
4913}
4914
4915void scene::add_a_group_of_things(int *Idx, int sz, int verbose_level)
4916{
4917 int f_v = (verbose_level >= 1);
4918 vector<int> v;
4919 int i;
4920
4921 if (f_v) {
4922 cout << "scene::add_a_group_of_things" << endl;
4923 }
4924
4925 for (i = 0; i < sz; i++) {
4926 v.push_back(Idx[i]);
4927 }
4928
4929 group_of_things.push_back(v);
4930
4931 //f_group_is_animated.push_back(FALSE);
4932
4933 if (f_v) {
4934 cout << "scene::add_a_group_of_things done" << endl;
4935 }
4936}
4937
4938
4939
4940
4941}}}
4942
functions related to strings and character arrays
various functions related to geometries
Definition: geometry.h:721
void AG_element_unrank(int q, int *v, int stride, int len, long int a)
a collection of 3D geometry objects
Definition: graphics.h:1152
int line_through_two_pts(double *x6, double rad)
Definition: scene.cpp:821
void draw_lines_cij(std::ostream &ost)
Definition: scene.cpp:1565
void draw_lines_cij_with_selection(int *selection, int nb_select, std::ostream &ost)
Definition: scene.cpp:1529
int line_extended(double x1, double x2, double x3, double y1, double y2, double y3, double r)
Definition: scene.cpp:2438
void transform_quartics(scene *S, double *A4, double *A4_inv, int verbose_level)
Definition: scene.cpp:647
void draw_planes_with_selection(int *selection, int nb_select, std::string &options, std::ostream &ost)
Definition: scene.cpp:1851
void draw_points_with_selection(int *selection, int nb_select, double rad, std::string &options, std::ostream &ost)
Definition: scene.cpp:1910
void add_a_group_of_things(int *Idx, int sz, int verbose_level)
Definition: scene.cpp:4915
int point(double x1, double x2, double x3)
Definition: scene.cpp:967
void draw_plane(int idx, std::string &options, std::ostream &ost)
Definition: scene.cpp:1883
void create_Hilbert_cube(int verbose_level)
Definition: scene.cpp:4096
void create_E4_surface(int N, int verbose_level)
Definition: scene.cpp:4566
int line_pt_and_dir_and_copy_points(double *x6, double rad, int verbose_level)
Definition: scene.cpp:776
void draw_quadric_with_selection(int *selection, int nb_select, std::string &options, std::ostream &ost)
Definition: scene.cpp:2092
void transform_quadrics(scene *S, double *A4, double *A4_inv, int verbose_level)
Definition: scene.cpp:589
int line_pt_and_dir(double *x6, double rad, int verbose_level)
Definition: scene.cpp:734
void rescale(int first_pt_idx, double rad_desired)
Definition: scene.cpp:2712
int cubic_Goursat_ABC(double A, double B, double C)
Definition: scene.cpp:1376
int line(double x1, double x2, double x3, double y1, double y2, double y3)
Definition: scene.cpp:871
void create_Eckardt_surface(int N, int verbose_level)
Definition: scene.cpp:4319
int point_center_of_mass_of_edge(int edge_idx)
Definition: scene.cpp:985
int point_as_intersection_of_two_lines(int line1, int line2)
Definition: scene.cpp:1017
std::vector< std::vector< int > > group_of_things
Definition: graphics.h:1217
void map_a_line(int line1, int line2, int plane_idx, int line_idx, double spread, int nb_pts, int *New_line_idx, int &nb_new_lines, int *New_pt_idx, int &nb_new_points, int verbose_level)
Definition: scene.cpp:2486
void create_affine_space(int q, int verbose_level)
Definition: scene.cpp:4258
int plane_through_three_points(int pt1, int pt2, int pt3)
Definition: scene.cpp:1107
void draw_lines_cij_with_offset(int offset, int number_of_lines, std::ostream &ost)
Definition: scene.cpp:1572
double label(int idx, std::string &txt)
Definition: scene.cpp:194
int triangle(int line1, int line2, int line3, int verbose_level)
Definition: scene.cpp:999
int face3(int pt1, int pt2, int pt3)
Definition: scene.cpp:1422
void points(double *Coords, int nb_points)
Definition: scene.cpp:958
void draw_lines_ai_with_selection(int *selection, int nb_select, std::ostream &ost)
Definition: scene.cpp:1583
void draw_lines_bj_with_selection(int *selection, int nb_select, std::ostream &ost)
Definition: scene.cpp:1637
void draw_lines_ai(std::ostream &ost)
Definition: scene.cpp:1619
void create_cube_and_tetrahedra(int verbose_level)
Definition: scene.cpp:4209
void create_Cayleys_nodal_cubic(int verbose_level)
Definition: scene.cpp:3991
void draw_octic_with_selection(int *selection, int nb_select, std::string &options, std::ostream &ost)
Definition: scene.cpp:2055
int point_center_of_mass_of_face(int face_idx)
Definition: scene.cpp:980
void copy_edges(scene *S, double *A4, double *A4_inv, int verbose_level)
Definition: scene.cpp:497
void draw_lines_bj_with_offset(int offset, std::ostream &ost)
Definition: scene.cpp:1680
void copy_faces(scene *S, double *A4, double *A4_inv, int verbose_level)
Definition: scene.cpp:711
int face5(int pt1, int pt2, int pt3, int pt4, int pt5)
Definition: scene.cpp:1443
int line_after_recentering(double x1, double x2, double x3, double y1, double y2, double y3, double rad)
Definition: scene.cpp:888
void transform_planes(scene *S, double *A4, double *A4_inv, int verbose_level)
Definition: scene.cpp:556
void draw_line_clipped_by_plane(int line_idx, int plane_idx, std::string &options, std::ostream &ost)
Definition: scene.cpp:2162
int intersect_line_and_line(int line1_idx, int line2_idx, double &lambda, int verbose_level)
Definition: scene.cpp:2408
int map_a_point(int line1, int line2, int plane_idx, double pt_in[3], int &new_line_idx, int &new_pt_idx, int verbose_level)
Definition: scene.cpp:2545
double quadric_coords(int idx, int j)
Definition: scene.cpp:269
void deformation_of_cubic_lex(int nb_frames, double angle_start, double angle_max, double angle_min, double *coeff1, double *coeff2, int verbose_level)
Definition: scene.cpp:1325
void transform_points(scene *S, double *A4, double *A4_inv, int verbose_level)
Definition: scene.cpp:519
void draw_quintic_with_selection(int *selection, int nb_select, std::string &options, std::ostream &ost)
Definition: scene.cpp:2018
int intersect_line_and_plane(int line_idx, int plane_idx, int &intersection_point_idx, int verbose_level)
Definition: scene.cpp:2209
int face4(int pt1, int pt2, int pt3, int pt4)
Definition: scene.cpp:1432
void draw_line_with_selection(int line_idx, std::string &options, std::ostream &ost)
Definition: scene.cpp:1494
void Dodecahedron_edges(int first_pt_idx)
Definition: scene.cpp:2931
std::vector< std::pair< int, std::string > > Labels
Definition: graphics.h:1191
void fourD_cube_edges(int first_pt_idx)
Definition: scene.cpp:2755
void draw_face(int idx, double thickness_half, std::string &options, std::ostream &ost)
Definition: scene.cpp:1754
void transform_quintics(scene *S, double *A4, double *A4_inv, int verbose_level)
Definition: scene.cpp:679
void create_twisted_cubic(int N, int verbose_level)
Definition: scene.cpp:4611
void read_obj_file(std::string &fname, int verbose_level)
Definition: scene.cpp:4757
double distance_euclidean_point_to_point(int pt1_idx, int pt2_idx)
Definition: scene.cpp:327
void create_triangulation_of_cube(int N, int verbose_level)
Definition: scene.cpp:4666
void draw_edges_with_selection(int *selection, int nb_select, std::string &options, std::ostream &ost)
Definition: scene.cpp:1694
void draw_quartic_with_selection(int *selection, int nb_select, std::string &options, std::ostream &ost)
Definition: scene.cpp:1981
double point_distance_from_origin(int pt_idx)
Definition: scene.cpp:318
void create_Hilbert_Cohn_Vossen_surface(int verbose_level)
Definition: scene.cpp:3458
int line_through_two_points(int pt1, int pt2, double rad)
Definition: scene.cpp:920
void draw_faces_with_selection(int *selection, int nb_select, double thickness_half, std::string &options, std::ostream &ost)
Definition: scene.cpp:1732
int point_center_of_mass(int *Pt_idx, int nb_pts)
Definition: scene.cpp:990
void transform_cubics(scene *S, double *A4, double *A4_inv, int verbose_level)
Definition: scene.cpp:618
int plane(double x1, double x2, double x3, double a)
Definition: scene.cpp:1073
scene * transformed_copy(double *A4, double *A4_inv, double rad, int verbose_level)
Definition: scene.cpp:369
void draw_cubic_with_selection(int *selection, int nb_select, std::string &options, std::ostream &ost)
Definition: scene.cpp:1944
int quadric_through_three_lines(int line_idx1, int line_idx2, int line_idx3, int verbose_level)
Definition: scene.cpp:1132
double distance_between_two_points(int pt1, int pt2)
Definition: scene.cpp:3370
void transform_lines(scene *S, double *A4, double *A4_inv, double rad, int verbose_level)
Definition: scene.cpp:441
void draw_lines_bj(std::ostream &ost)
Definition: scene.cpp:1673
void draw_quadric_clipped_by_plane(int quadric_idx, int plane_idx, std::string &options, std::ostream &ost)
Definition: scene.cpp:2123
void draw_lines_with_selection(int *selection, int nb_select, std::string &options, std::ostream &ost)
Definition: scene.cpp:1457
void Dodecahedron_planes(int first_pt_idx)
Definition: scene.cpp:2958
void create_Hilbert_model(int verbose_level)
Definition: scene.cpp:3503
double point_distance_euclidean(int pt_idx, double *y)
Definition: scene.cpp:309
void hypercube(int n, double rad_desired)
Definition: scene.cpp:2786
double euclidean_distance(int pt1, int pt2)
Definition: scene.cpp:2735
void create_Clebsch_surface(int verbose_level)
Definition: scene.cpp:3404
void draw_lines_ai_with_offset(int offset, std::ostream &ost)
Definition: scene.cpp:1626
void fourD_cube(double rad_desired)
Definition: scene.cpp:2670
numerical functions, mostly concerned with double
Definition: globals.h:129
int triangular_prism(double *P1, double *P2, double *P3, double *abc3, double *angles3, double *T3, int verbose_level)
Definition: numerics.cpp:458
void vec_add(double *a, double *b, double *c, int len)
Definition: numerics.cpp:82
void vec_linear_combination3(double c1, double *v1, double c2, double *v2, double c3, double *v3, double *w, int len)
Definition: numerics.cpp:69
int intersect_line_and_line(double *line1_pt1_coords, double *line1_pt2_coords, double *line2_pt1_coords, double *line2_pt2_coords, double &lambda, double *pt_coords, int verbose_level)
Definition: numerics.cpp:2811
double distance_euclidean(double *x, double *y, int len)
Definition: numerics.cpp:984
void vec_scalar_multiple(double *a, double lambda, int len)
Definition: numerics.cpp:100
void plane_through_three_points(double *p1, double *p2, double *p3, double *n, double &d)
Definition: numerics.cpp:1051
int Gauss_elimination(double *A, int m, int n, int *base_cols, int f_complete, int verbose_level)
Definition: numerics.cpp:109
void substitute_quadric_linear(double *coeff_in, double *coeff_out, double *A4_inv, int verbose_level)
Definition: numerics.cpp:1224
void print_system(double *A, int m, int n)
Definition: numerics.cpp:270
double distance_from_origin(double x1, double x2, double x3)
Definition: numerics.cpp:998
void vec_print(double *a, int len)
Definition: numerics.cpp:35
int general_prism(double *Pts, int nb_pts, double *Pts_xy, double *abc3, double *angles3, double *T3, int verbose_level)
Definition: numerics.cpp:631
void make_unit_vector(double *v, int len)
Definition: numerics.cpp:1019
void mult_matrix_4x4(double *v, double *R, double *vR)
Definition: numerics.cpp:1187
int Null_space(double *M, int m, int n, double *K, int verbose_level)
Definition: numerics.cpp:371
int line_centered(double *pt1_in, double *pt2_in, double *pt1_out, double *pt2_out, double r, int verbose_level)
Definition: numerics.cpp:1804
void output_double(double a, std::ostream &ost)
Definition: numerics.cpp:1177
void vec_subtract(double *a, double *b, double *c, int len)
Definition: numerics.cpp:91
int line_centered_tolerant(double *pt1_in, double *pt2_in, double *pt1_out, double *pt2_out, double r, int verbose_level)
Definition: numerics.cpp:1896
void center_of_mass(double *Pts, int len, int *Pt_idx, int nb_pts, double *c)
Definition: numerics.cpp:1032
void substitute_quartic_linear_using_povray_ordering(double *coeff_in, double *coeff_out, double *A4_inv, int verbose_level)
Definition: numerics.cpp:1517
void transpose_matrix_4x4(double *A, double *At)
Definition: numerics.cpp:1202
void vec_swap(double *from, double *to, int len)
Definition: numerics.cpp:2192
void substitute_cubic_linear_using_povray_ordering(double *coeff_in, double *coeff_out, double *A4_inv, int verbose_level)
Definition: numerics.cpp:1345
void vec_normalize_from_back(double *v, int len)
Definition: numerics.cpp:415
void vec_normalize_to_minus_one_from_back(double *v, int len)
Definition: numerics.cpp:435
void mult_matrix_matrix(double *A, double *B, double *C, int m, int n, int o)
Definition: numerics.cpp:855
void vec_copy(double *from, double *to, int len)
Definition: numerics.cpp:2182
void matrix_double_inverse(double *A, double *Av, int n, int verbose_level)
Definition: numerics.cpp:1752
#define FREE_int(p)
Definition: foundations.h:640
#define ONE_MILLION
Definition: foundations.h:226
#define NEW_pint(n)
Definition: foundations.h:627
#define NEW_char(n)
Definition: foundations.h:632
#define NEW_OBJECT(type)
Definition: foundations.h:638
#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 Int_vec_copy(A, B, C)
Definition: foundations.h:693
#define M_PI
Definition: foundations.h:237
#define FREE_pint(p)
Definition: foundations.h:641
#define Int_vec_print(A, B, C)
Definition: foundations.h:685
#define SCENE_MAX_QUINTICS
Definition: graphics.h:1143
#define SCENE_MAX_EDGES
Definition: graphics.h:1137
#define SCENE_MAX_PLANES
Definition: graphics.h:1139
#define SCENE_MAX_LINES
Definition: graphics.h:1136
#define SCENE_MAX_POINTS
Definition: graphics.h:1138
#define SCENE_MAX_OCTICS
Definition: graphics.h:1141
#define SCENE_MAX_CUBICS
Definition: graphics.h:1144
#define SCENE_MAX_QUARTICS
Definition: graphics.h:1142
#define SCENE_MAX_QUADRICS
Definition: graphics.h:1140
#define SCENE_MAX_FACES
Definition: graphics.h:1145
the orbiter library for the classification of combinatorial objects
#define EPSILON
Definition: scene.cpp:16
#define MY_OWN_BUFSIZE
Definition: scene.cpp:4755
#define scene_alpha
Definition: scene.cpp:3251
#define scene_beta
Definition: scene.cpp:3252