Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
point_test.cc
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
52#include <gtest/gtest.h>
53#include <cmath>
54#include <point.H>
55
56using namespace Aleph;
57
58// Tolerance for floating-point comparisons
59constexpr double EPSILON = 1e-9;
60
61// Helper to compare Geom_Number with tolerance
62bool approx_equal(const Geom_Number & a, const Geom_Number & b,
63 double tol = EPSILON)
64{
65 return std::abs(a.get_d() - b.get_d()) < tol;
66}
67
68bool approx_equal(double a, double b, double tol = EPSILON)
69{
70 return std::abs(a - b) < tol;
71}
72
73//============================================================================
74// Point Tests
75//============================================================================
76
77class PointTest : public ::testing::Test
78{
79protected:
80 Point origin;
81 Point p1{1, 2};
82 Point p2{3, 4};
83 Point p3{-1, -1};
84};
85
87{
88 EXPECT_EQ(origin.get_x(), 0);
89 EXPECT_EQ(origin.get_y(), 0);
90}
91
93{
94 EXPECT_EQ(p1.get_x(), 1);
95 EXPECT_EQ(p1.get_y(), 2);
96}
97
99{
100 Point p1_copy{1, 2};
101 EXPECT_EQ(p1, p1_copy);
102 EXPECT_NE(p1, p2);
103}
104
106{
107 Point sum = p1 + p2;
108 EXPECT_EQ(sum.get_x(), 4);
109 EXPECT_EQ(sum.get_y(), 6);
110}
111
113{
114 Point p = p1;
115 p += p2;
116 EXPECT_EQ(p.get_x(), 4);
117 EXPECT_EQ(p.get_y(), 6);
118}
119
121{
122 Point diff = p2 - p1;
123 EXPECT_EQ(diff.get_x(), 2);
124 EXPECT_EQ(diff.get_y(), 2);
125}
126
128{
129 Point p = p2;
130 p -= p1;
131 EXPECT_EQ(p.get_x(), 2);
132 EXPECT_EQ(p.get_y(), 2);
133}
134
136{
137 std::string str = origin.to_string();
138 EXPECT_FALSE(str.empty());
139 EXPECT_NE(str.find("0"), std::string::npos);
140}
141
143{
144 std::string str = static_cast<std::string>(p1);
145 EXPECT_FALSE(str.empty());
146}
147
149{
150 Point a{0, 0};
151 Point b{3, 4};
152 Geom_Number dist = a.distance_with(b);
153 EXPECT_TRUE(approx_equal(dist, 5.0));
154}
155
157{
158 Point a{0, 0};
159 Point b{3, 4};
160 Geom_Number dist_sq = a.distance_squared_to(b);
161 EXPECT_EQ(dist_sq, 25);
162}
163
165{
166 Point a{0, 0};
167 Point b{1, 1};
168 Point c{2, 2};
169 Point d{1, 0};
170
171 EXPECT_TRUE(a.is_colinear_with(b, c));
172 EXPECT_FALSE(a.is_colinear_with(b, d));
173}
174
176{
177 Point a{0, 0};
178 Point b{1, 0};
179 Point left{0.5, 1};
180 Point right{0.5, -1};
181
182 EXPECT_TRUE(left.is_to_left_from(a, b));
183 EXPECT_FALSE(right.is_to_left_from(a, b));
184}
185
187{
188 Point a{0, 0};
189 Point b{1, 0};
190 Point left{0.5, 1};
191 Point right{0.5, -1};
192
193 EXPECT_TRUE(right.is_to_right_from(a, b));
194 EXPECT_FALSE(left.is_to_right_from(a, b));
195}
196
198{
199 Point a{0, 0};
200 Point b{1, 0};
201 Point on_line{0.5, 0};
202 Point left{0.5, 1};
203
204 EXPECT_TRUE(on_line.is_to_left_on_from(a, b));
205 EXPECT_TRUE(left.is_to_left_on_from(a, b));
206}
207
209{
210 Point a{0, 0};
211 Point b{1, 0};
212 Point c{0.5, -1}; // Below line a-b -> clockwise
213
214 EXPECT_TRUE(a.is_clockwise_with(b, c));
215}
216
218{
219 Point a{0, 0};
220 Point b{2, 2};
221 Point between{1, 1};
222 Point outside{3, 3};
223
224 EXPECT_TRUE(between.is_between(a, b));
225 EXPECT_FALSE(outside.is_between(a, b));
226}
227
229{
230 Point ref{0, 0};
231 Point near{1, 1};
232 Point far{10, 10};
233
234 const Point & nearest = ref.nearest_point(near, far);
235 EXPECT_EQ(nearest, near);
236}
237
239{
240 EXPECT_EQ(p1.highest_point(), p1);
241 EXPECT_EQ(p1.lowest_point(), p1);
242 EXPECT_EQ(p1.leftmost_point(), p1);
243 EXPECT_EQ(p1.rightmost_point(), p1);
244}
245
246//============================================================================
247// Polar_Point Tests
248//============================================================================
249
250class PolarPointTest : public ::testing::Test
251{
252protected:
253 Point cartesian{3, 4};
255};
256
261
263{
264 Point back(polar);
265 EXPECT_TRUE(approx_equal(back.get_x(), 3.0));
266 EXPECT_TRUE(approx_equal(back.get_y(), 4.0));
267}
268
278
280{
281 Point p{1, 1};
282 Polar_Point pp{p};
283 EXPECT_EQ(pp.get_quadrant(), Polar_Point::First);
284}
285
287{
288 Point p{-1, 1};
289 Polar_Point pp{p};
290 EXPECT_EQ(pp.get_quadrant(), Polar_Point::Second);
291}
292
294{
295 Point p{-1, -1};
296 Polar_Point pp{p};
297 EXPECT_EQ(pp.get_quadrant(), Polar_Point::Third);
298}
299
301{
302 Point p{1, -1};
303 Polar_Point pp{p};
304 EXPECT_EQ(pp.get_quadrant(), Polar_Point::Fourth);
305}
306
308{
309 std::string str = polar.to_string();
310 EXPECT_FALSE(str.empty());
311 EXPECT_EQ(str[0], '[');
312}
313
315{
317 EXPECT_EQ(pp.get_r(), 0);
318 EXPECT_EQ(pp.get_theta(), 0);
319}
320
321//============================================================================
322// Segment Tests
323//============================================================================
324
325class SegmentTest : public ::testing::Test
326{
327protected:
328 Point origin{0, 0};
329 Point p1{1, 0};
330 Point p2{0, 1};
331 Point p3{1, 1};
332
336};
337
339{
340 Segment s;
341 // Should not crash
342}
343
345{
346 EXPECT_EQ(horizontal.get_src_point(), origin);
347 EXPECT_EQ(horizontal.get_tgt_point(), p1);
348}
349
351{
352 Segment s1{origin, p1};
353 Segment s2{origin, p1};
354 Segment s3{origin, p2};
355
356 EXPECT_EQ(s1, s2);
357 EXPECT_NE(s1, s3);
358}
359
361{
362 Geom_Number len = horizontal.size();
363 EXPECT_TRUE(approx_equal(len, 1.0));
364
365 Segment longer{Point{0, 0}, Point{3, 4}};
367}
368
370{
371 EXPECT_TRUE(approx_equal(horizontal.slope(), 0.0));
372 EXPECT_TRUE(approx_equal(diagonal.slope(), 1.0));
373}
374
376{
377 Point mid = diagonal.mid_point();
378 EXPECT_TRUE(approx_equal(mid.get_x(), 0.5));
379 EXPECT_TRUE(approx_equal(mid.get_y(), 0.5));
380}
381
383{
384 Segment s{Point{0, 0}, Point{1, 2}};
385 const Point & h = s.highest_point();
386 EXPECT_EQ(h.get_y(), 2);
387}
388
390{
391 Segment s{Point{0, 0}, Point{1, 2}};
392 const Point & l = s.lowest_point();
393 EXPECT_EQ(l.get_y(), 0);
394}
395
397{
398 Segment s{Point{2, 0}, Point{0, 1}};
399 const Point & l = s.leftmost_point();
400 EXPECT_EQ(l.get_x(), 0);
401}
402
404{
405 Segment s{Point{2, 0}, Point{0, 1}};
406 const Point & r = s.rightmost_point();
407 EXPECT_EQ(r.get_x(), 2);
408}
409
411{
412 Point inside{0.5, 0.5};
413 Point outside{2, 2};
414
415 EXPECT_TRUE(diagonal.contains_to(inside));
416 EXPECT_FALSE(diagonal.contains_to(outside));
417}
418
420{
421 Point colinear{0.5, 0.5};
422 Point not_colinear{0.5, 0.6};
423
424 EXPECT_TRUE(diagonal.is_colinear_with(colinear));
425 EXPECT_FALSE(diagonal.is_colinear_with(not_colinear));
426}
427
429{
430 Segment s1{Point{0, 0}, Point{1, 1}};
431 Segment s2{Point{1, 0}, Point{2, 1}}; // Parallel
432 Segment s3{Point{0, 0}, Point{1, 0}}; // Not parallel
433
434 EXPECT_TRUE(s1.is_parallel_with(s2));
435 EXPECT_FALSE(s1.is_parallel_with(s3));
436}
437
439{
440 Segment s1{Point{0, 0}, Point{2, 2}};
441 Segment s2{Point{0, 2}, Point{2, 0}}; // Cross
442 Segment s3{Point{3, 0}, Point{4, 0}}; // No intersection
443
444 EXPECT_TRUE(s1.intersects_with(s2));
445 EXPECT_FALSE(s1.intersects_with(s3));
446}
447
449{
450 Segment s1{Point{0, 0}, Point{2, 2}};
451 Segment s2{Point{0, 2}, Point{2, 0}}; // Proper cross
452
453 EXPECT_TRUE(s1.intersects_properly_with(s2));
454}
455
457{
458 Segment s1{Point{0, 0}, Point{2, 2}};
459 Segment s2{Point{0, 2}, Point{2, 0}};
460
461 Point inter = s1.intersection_with(s2);
462 EXPECT_TRUE(approx_equal(inter.get_x(), 1.0));
463 EXPECT_TRUE(approx_equal(inter.get_y(), 1.0));
464}
465
467{
468 Segment s1{Point{0, 0}, Point{1, 1}};
469 Segment s2{Point{0, 1}, Point{1, 2}}; // Parallel
470
471 EXPECT_THROW(s1.intersection_with(s2), std::domain_error);
472}
473
475{
476 Segment s{Point{0, 0}, Point{1, 0}};
477 EXPECT_EQ(s.sense(), Segment::E);
478}
479
481{
482 Segment s{Point{1, 0}, Point{0, 0}};
483 EXPECT_EQ(s.sense(), Segment::W);
484}
485
487{
488 Segment s{Point{0, 0}, Point{0, 1}};
489 EXPECT_EQ(s.sense(), Segment::N);
490}
491
493{
494 Segment s{Point{0, 1}, Point{0, 0}};
495 EXPECT_EQ(s.sense(), Segment::S);
496}
497
499{
500 Segment s{Point{0, 0}, Point{1, 1}};
501 EXPECT_EQ(s.sense(), Segment::NE);
502}
503
505{
506 Segment s{Point{1, 1}, Point{0, 0}};
507 EXPECT_EQ(s.sense(), Segment::SW);
508}
509
511{
512 Segment s{Point{1, 0}, Point{0, 1}};
513 EXPECT_EQ(s.sense(), Segment::NW);
514}
515
517{
518 Segment s{Point{0, 1}, Point{1, 0}};
519 EXPECT_EQ(s.sense(), Segment::SE);
520}
521
523{
524 std::string str = diagonal.to_string();
525 EXPECT_FALSE(str.empty());
526}
527
529{
530 Segment s{Point{0, 0}, Point{1, 0}};
531 s.rotate(PI / 2); // Rotate 90 degrees
532
533 EXPECT_TRUE(approx_equal(s.get_tgt_point().get_x(), 0.0, 1e-6));
534 EXPECT_TRUE(approx_equal(s.get_tgt_point().get_y(), 1.0, 1e-6));
535}
536
538{
539 Segment s{Point{0, 0}, Point{2, 0}};
540 Point p{1, 1};
541
542 Segment perp = s.get_perpendicular(p);
543 // Perpendicular from (1,1) to horizontal line should hit (1,0)
544 EXPECT_TRUE(approx_equal(perp.get_src_point().get_x(), 1.0, 1e-6));
545 EXPECT_TRUE(approx_equal(perp.get_src_point().get_y(), 0.0, 1e-6));
546}
547
549{
550 Segment s{Point{0, 0}, Point{1, 0}};
551 double angle = s.counterclockwise_angle();
552 EXPECT_TRUE(approx_equal(angle, 0.0, 1e-6));
553}
554
555//============================================================================
556// Triangle Tests
557//============================================================================
558
559class TriangleTest : public ::testing::Test
560{
561protected:
562 Point p1{0, 0};
563 Point p2{4, 0};
564 Point p3{0, 3};
566};
567
569{
570 EXPECT_EQ(t.get_p1(), p1);
571 EXPECT_EQ(t.get_p2(), p2);
572 EXPECT_EQ(t.get_p3(), p3);
573}
574
576{
577 Segment s{p2, p3};
578 Triangle t2{p1, s};
579
580 EXPECT_EQ(t2.get_p1(), p1);
581}
582
584{
585 Segment s{p1, p2};
586 Triangle t2{s, p3};
587
588 EXPECT_EQ(t2.get_p3(), p3);
589}
590
592{
593 Point a{0, 0};
594 Point b{1, 1};
595 Point c{2, 2};
596
597 EXPECT_THROW(Triangle(a, b, c), std::domain_error);
598}
599
601{
602 // 3-4-5 right triangle has area = (1/2)*3*4 = 6
603 Geom_Number area = t.area();
604 EXPECT_EQ(area, 6);
605}
606
608{
609 Point inside{1, 1};
610 Point outside{5, 5};
611
612 EXPECT_TRUE(t.contains_to(inside));
613 EXPECT_FALSE(t.contains_to(outside));
614}
615
617{
618 const Point & h = t.highest_point();
619 EXPECT_EQ(h.get_y(), 3);
620}
621
623{
624 const Point & l = t.lowest_point();
625 EXPECT_EQ(l.get_y(), 0);
626}
627
629{
630 const Point & l = t.leftmost_point();
631 EXPECT_EQ(l.get_x(), 0);
632}
633
635{
636 const Point & r = t.rightmost_point();
637 EXPECT_EQ(r.get_x(), 4);
638}
639
641{
642 // Counter-clockwise triangle
643 Triangle ccw{Point{0,0}, Point{1,0}, Point{0,1}};
644
645 // Clockwise triangle
646 Triangle cw{Point{0,0}, Point{0,1}, Point{1,0}};
647
648 // Note: the is_clockwise check depends on sign of area
649 EXPECT_NE(ccw.is_clockwise(), cw.is_clockwise());
650}
651
652//============================================================================
653// Rectangle Tests
654//============================================================================
655
656class RectangleTest : public ::testing::Test
657{
658protected:
659 Rectangle r{0, 0, 4, 3};
660};
661
663{
665 EXPECT_EQ(r_default.get_xmin(), 0);
666 EXPECT_EQ(r_default.get_ymin(), 0);
667 EXPECT_EQ(r_default.get_xmax(), 0);
668 EXPECT_EQ(r_default.get_ymax(), 0);
669}
670
672{
673 EXPECT_EQ(r.get_xmin(), 0);
674 EXPECT_EQ(r.get_ymin(), 0);
675 EXPECT_EQ(r.get_xmax(), 4);
676 EXPECT_EQ(r.get_ymax(), 3);
677}
678
680{
681 EXPECT_THROW(Rectangle(4, 0, 0, 3), std::range_error); // xmax < xmin
682 EXPECT_THROW(Rectangle(0, 3, 4, 0), std::range_error); // ymax < ymin
683}
684
686{
687 EXPECT_EQ(r.width(), 4);
688}
689
691{
692 EXPECT_EQ(r.height(), 3);
693}
694
696{
697 Point inside{2, 1};
698 Point outside{5, 5};
699 Point on_edge{0, 0};
700
701 EXPECT_TRUE(r.contains(inside));
702 EXPECT_FALSE(r.contains(outside));
703 EXPECT_TRUE(r.contains(on_edge));
704}
705
707{
708 Rectangle r2{2, 1, 6, 4}; // Overlaps
709 Rectangle r3{5, 5, 6, 6}; // No overlap
710
711 EXPECT_TRUE(r.intersects(r2));
712 EXPECT_FALSE(r.intersects(r3));
713}
714
716{
717 Point inside{2, 1};
718 Point outside{5, 0}; // Distance 1 from right edge
719
720 EXPECT_EQ(r.distance_squared_to(inside), 0);
721 EXPECT_EQ(r.distance_squared_to(outside), 1);
722}
723
725{
726 Point outside{5, 0};
727 Geom_Number dist = r.distance_to(outside);
728 EXPECT_TRUE(approx_equal(dist, 1.0));
729}
730
732{
734 r_mod.set_rect(1, 2, 3, 4);
735
736 EXPECT_EQ(r_mod.get_xmin(), 1);
737 EXPECT_EQ(r_mod.get_ymin(), 2);
738 EXPECT_EQ(r_mod.get_xmax(), 3);
739 EXPECT_EQ(r_mod.get_ymax(), 4);
740}
741
743{
745 EXPECT_THROW(r_mod.set_rect(3, 2, 1, 4), std::range_error);
746}
747
748//============================================================================
749// Ellipse Tests
750//============================================================================
751
752class EllipseTest : public ::testing::Test
753{
754protected:
755 Point center{0, 0};
756 Ellipse circle{center, 1, 1}; // Unit circle
757 Ellipse ellipse{center, 2, 1}; // Horizontal ellipse
758};
759
761{
762 Ellipse e;
763 // Should not crash
764}
765
767{
768 EXPECT_EQ(ellipse.get_center(), center);
769 EXPECT_EQ(ellipse.get_hradius(), 2);
770 EXPECT_EQ(ellipse.get_vradius(), 1);
771}
772
774{
775 Ellipse e2{ellipse};
776 EXPECT_EQ(e2.get_center(), ellipse.get_center());
777 EXPECT_EQ(e2.get_hradius(), ellipse.get_hradius());
778 EXPECT_EQ(e2.get_vradius(), ellipse.get_vradius());
779}
780
782{
783 Point h = ellipse.highest_point();
784 EXPECT_EQ(h.get_x(), 0);
785 EXPECT_EQ(h.get_y(), 1);
786}
787
789{
790 Point l = ellipse.lowest_point();
791 EXPECT_EQ(l.get_x(), 0);
792 EXPECT_EQ(l.get_y(), -1);
793}
794
796{
797 Point l = ellipse.leftmost_point();
798 EXPECT_EQ(l.get_x(), -2);
799 EXPECT_EQ(l.get_y(), 0);
800}
801
803{
804 Point r = ellipse.rightmost_point();
805 EXPECT_EQ(r.get_x(), 2);
806 EXPECT_EQ(r.get_y(), 0);
807}
808
810{
811 EXPECT_TRUE(circle.contains_to(center));
812}
813
815{
816 Point inside{0.5, 0.5};
817 EXPECT_TRUE(circle.contains_to(inside));
818}
819
821{
822 Point outside{2, 2};
823 EXPECT_FALSE(circle.contains_to(outside));
824}
825
827{
828 Point on_border{1, 0};
829 EXPECT_TRUE(circle.contains_to(on_border));
830}
831
833{
834 Point on_border{1, 0};
835 EXPECT_TRUE(circle.intersects_with(on_border));
836}
837
842
844{
845 Point inside{0.5, 0};
846 EXPECT_TRUE(inside.is_inside(circle));
847}
848
849//============================================================================
850// Helper Function Tests
851//============================================================================
852
854{
855 Point a{0, 0};
856 Point b{1, 0};
857 Point c{0, 1};
858
859 Geom_Number area = area_of_parallelogram(a, b, c);
860 EXPECT_EQ(area, 1);
861}
862
864{
865 Point a{0, 0};
866 Point b{0, 1};
867 Point c{1, 0};
868
869 Geom_Number area = area_of_parallelogram(a, b, c);
870 EXPECT_EQ(area, -1);
871}
872
874{
875 Geom_Number result = pitag(3, 4);
876 EXPECT_TRUE(approx_equal(result, 5.0));
877}
878
880{
881 Geom_Number result = pitag(0, 0);
882 EXPECT_TRUE(approx_equal(result, 0.0));
883}
884
886{
887 Geom_Number result = arctan(1);
888 EXPECT_TRUE(approx_equal(result.get_d(), PI / 4, 1e-6));
889}
890
892{
893 Geom_Number result = arctan2(1, 1);
894 EXPECT_TRUE(approx_equal(result.get_d(), PI / 4, 1e-6));
895}
896
898{
899 Geom_Number result = sinus(Geom_Number(PI / 2));
900 EXPECT_TRUE(approx_equal(result.get_d(), 1.0, 1e-6));
901}
902
904{
905 Geom_Number result = cosinus(0);
906 EXPECT_TRUE(approx_equal(result.get_d(), 1.0, 1e-6));
907}
908
910{
911 Geom_Number result = square_root(4);
912 EXPECT_TRUE(approx_equal(result.get_d(), 2.0, 1e-6));
913}
914
916{
917 Geom_Number n{3.14159};
918 double d = geom_number_to_double(n);
919 EXPECT_TRUE(approx_equal(d, 3.14159, 1e-4));
920}
921
922//============================================================================
923// Text and String Utility Tests
924//============================================================================
925
927{
928 std::string str = "hello";
929 size_t len = aproximate_string_size(str);
930 EXPECT_EQ(len, 5);
931}
932
934{
935 std::string str = "\\alpha"; // Latex command counts as 1
936 size_t len = aproximate_string_size(str);
937 EXPECT_EQ(len, 1);
938}
939
941{
942 std::string str = "$x$"; // $ signs are skipped
943 size_t len = aproximate_string_size(str);
944 EXPECT_EQ(len, 1); // Only 'x' counts
945}
946
948{
949 std::string str = "{ab}";
950 size_t len = aproximate_string_size(str);
951 EXPECT_EQ(len, 2); // Only 'a' and 'b' count
952}
953
955{
956 Point p{1, 2};
957 Text t{p, "Hello"};
958
959 EXPECT_EQ(t.get_point(), p);
960 EXPECT_EQ(t.get_str(), "Hello");
961 EXPECT_EQ(t.len(), 5);
962}
963
965{
966 Text t;
967 // Should not crash
968}
969
971{
972 Point p{1, 2};
973 Text t{p, "test"};
974
975 EXPECT_EQ(t.highest_point(), p);
976 EXPECT_EQ(t.lowest_point(), p);
977 EXPECT_EQ(t.leftmost_point(), p);
978 EXPECT_EQ(t.rightmost_point(), p);
979}
980
981//============================================================================
982// Geom_Object Tests
983//============================================================================
984
986{
987 // Test that virtual destructor works properly
988 Geom_Object *obj = new Point{1, 2};
989 delete obj; // Should not crash
990}
991
992//============================================================================
993// NullPoint Tests
994//============================================================================
995
997{
998 // NullPoint should be defined and accessible
1001}
1002
1003//============================================================================
1004// Edge Cases and Regression Tests
1005//============================================================================
1006
1008{
1009 Segment vertical{Point{0, 0}, Point{0, 1}};
1010 double slope = vertical.slope();
1011 EXPECT_GT(slope, 1e10); // Should be very large positive
1012}
1013
1015{
1016 Segment vertical{Point{0, 1}, Point{0, 0}};
1017 double slope = vertical.slope();
1018 EXPECT_LT(slope, -1e10); // Should be very large negative
1019}
1020
1022{
1023 Point src{0, 0};
1024 Geom_Number slope{1}; // 45 degrees
1025 Geom_Number length{std::sqrt(2)};
1026
1027 Segment s{src, slope, length};
1028
1029 EXPECT_TRUE(approx_equal(s.size(), length, 1e-6));
1030}
1031
1033{
1034 Segment original{Point{0, 0}, Point{2, 0}};
1035 Geom_Number dist{1};
1036
1037 Segment parallel{original, dist};
1038
1039 // Parallel segment should have same length
1041}
1042
1044{
1045 Segment s{Point{1, 0}, Point{2, 0}};
1047
1048 s.enlarge_src(1);
1049
1050 // Segment should be longer now
1051 EXPECT_GT(s.size(), original_size);
1052}
1053
1055{
1056 Segment s{Point{0, 0}, Point{1, 0}};
1058
1059 s.enlarge_tgt(1);
1060
1061 // Segment should be longer now
1062 EXPECT_GT(s.size(), original_size);
1063}
1064
1066{
1067 // Points on a line should fail to create a triangle
1068 EXPECT_THROW(Triangle(Point{0,0}, Point{1,1}, Point{2,2}), std::domain_error);
1069}
1070
1072{
1073 Segment s{Point{0, 0}, Point{2, 2}};
1074 Point on_segment{1, 1};
1075
1076 EXPECT_TRUE(on_segment.is_inside(s));
1077}
1078
1080{
1081 Segment s{Point{0, 0}, Point{2, 0}};
1082 Segment perp = s.mid_perpendicular(1);
1083
1084 // Midpoint of perpendicular should be near midpoint of original
1085 Point mid = s.mid_point();
1086 Point perp_mid = perp.mid_point();
1087
1088 EXPECT_TRUE(approx_equal(mid.distance_with(perp_mid), 0.0, 1e-6));
1089}
1090
1091//============================================================================
1092// Segment-Triangle Intersection Tests
1093//============================================================================
1094
1096{
1097 Triangle t{Point{0, 0}, Point{4, 0}, Point{2, 4}};
1098 Segment s{Point{2, -1}, Point{2, 5}}; // Vertical through triangle
1099
1100 EXPECT_TRUE(s.intersects_with(t));
1101}
1102
1104{
1105 Triangle t{Point{0, 0}, Point{4, 0}, Point{2, 4}};
1106 Segment s{Point{10, 10}, Point{11, 11}}; // Far away
1107
1108 EXPECT_FALSE(s.intersects_with(t));
1109}
1110
1111//============================================================================
1112// Main
1113//============================================================================
1114
1115int main(int argc, char **argv)
1116{
1117 testing::InitGoogleTest(&argc, argv);
1118 return RUN_ALL_TESTS();
1119}
int main()
long double h
Definition btreepic.C:154
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
Ellipse ellipse
Ellipse circle
static bool is_clockwise()
Definition point.H:1184
Point origin
Definition point_test.cc:80
Rectangular point in the plane.
Definition point.H:156
const Geom_Number & get_y() const
Returns y value.
Definition point.H:226
const Point & highest_point() const
Definition point.H:321
const Point & rightmost_point() const
Definition point.H:327
const Geom_Number & get_x() const
Returns x value.
Definition point.H:221
Polar_Point polar
Polar representation of a 2D point.
Definition point.H:343
Rectangle r
Segment diagonal
Segment vertical
Segment horizontal
Fundamental segment defined by two points.
Definition point.H:417
@ SE
Definition point.H:756
@ N
Definition point.H:756
@ NW
Definition point.H:756
@ W
Definition point.H:756
@ E
Definition point.H:756
@ NE
Definition point.H:756
@ SW
Definition point.H:756
@ S
Definition point.H:756
Definition point.H:1524
#define TEST(name)
bool vertical
If true, use vertical layout (default).
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
bool diff(const C1 &c1, const C2 &c2, Eq e=Eq())
Check if two containers differ.
DynList< T > maps(const C &c, Op op)
Classic map operation.
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
const Point NullPoint
Definition point.C:41
2D point and geometric utilities.
mpq_class Geom_Number
Numeric type used by the geometry module.
Definition point.H:68
constexpr double PI
Definition point.H:85
Geom_Number pitag(const Geom_Number &x, const Geom_Number &y)
Return the Euclidean distance.
Definition point.H:104
Geom_Number arctan2(const Geom_Number &m, const Geom_Number &n)
Two-argument arc tangent (wrapper over mpfr).
Definition point.H:116
double geom_number_to_double(const Geom_Number &n)
Definition point.H:70
Geom_Number arctan(const Geom_Number &m)
Arc tangent of m (wrapper over mpfr).
Definition point.H:110
Geom_Number square_root(const Geom_Number &x)
Square root of x (wrapper over mpfr).
Definition point.H:134
Geom_Number cosinus(const Geom_Number &x)
Cosine of x (wrapper over mpfr).
Definition point.H:128
Geom_Number sinus(const Geom_Number &x)
Sine of x (wrapper over mpfr).
Definition point.H:122
size_t aproximate_string_size(const std::string &str)
Definition point.H:1489
Geom_Number area_of_parallelogram(const Point &a, const Point &b, const Point &c)
Compute the area of parallelogram defined by vectors a->b and b->c.
Definition point.H:1577
constexpr double EPSILON
Definition point_test.cc:59
TEST_F(PointTest, DefaultConstruction)
Definition point_test.cc:86
bool approx_equal(const Geom_Number &a, const Geom_Number &b, double tol=EPSILON)
Definition point_test.cc:62
const bool between(const Point &a, const Point &b, const Point &c)
Test if point c is between points a and b.
DynList< int > l