78TEST(EllipticalArcTest, LineSegmentIntersection) {
79 std::vector<CurveIntersection> r1;
83 EXPECT_EQ(r1.size(), 2u);
84 EXPECT_intersections_valid(a3, ls, r1, 1e-10);
86 g_random_set_seed(0xB747A380);
88 for (
size_t _ = 0; _ < 10'000; _++) {
89 auto arc =
EllipticalArc({g_random_double_range(1.0, 5.0), 0.0},
90 {g_random_double_range(6.0, 8.0), g_random_double_range(2.0, 7.0)},
91 g_random_double_range(-0.5, 0.5),
true, g_random_boolean(),
92 {g_random_double_range(-5.0, -1.0), 0.0});
93 Coord x = g_random_double_range(15, 30);
94 Coord y = g_random_double_range(10, 20);
96 auto xings = arc.intersect(seg);
97 EXPECT_EQ(xings.size(), 1u);
98 EXPECT_intersections_valid(arc, seg, xings, 1e-12);
102 EllipticalArc x_squash_pos{{3.0, 0.0}, {3.0, 2.0}, 0,
true,
true, {-3.0, 0.0}};
103 EllipticalArc x_squash_neg{{3.0, 0.0}, {3.0, 2.0}, 0,
true,
false, {-3.0, 0.0}};
104 auto const squash_to_x =
Scale(1.0, 0.0);
105 x_squash_pos *= squash_to_x;
106 x_squash_neg *= squash_to_x;
108 for (
size_t _ = 0; _ < 10'000; _++) {
109 auto seg =
LineSegment(
Point(g_random_double_range(-3.0, 3.0), g_random_double_range(-3.0, -1.0)),
110 Point(g_random_double_range(-3.0, 3.0), g_random_double_range(1.0, 3.0)));
111 auto xings = x_squash_pos.intersect(seg);
112 EXPECT_EQ(xings.size(), 1u);
113 EXPECT_intersections_valid(x_squash_pos, seg, xings, 1e-12);
115 std::unique_ptr<Curve> rev{x_squash_pos.reverse()};
116 xings = rev->intersect(seg);
117 EXPECT_EQ(xings.size(), 1u);
118 EXPECT_intersections_valid(*rev, seg, xings, 1e-12);
120 xings = x_squash_neg.intersect(seg);
121 EXPECT_EQ(xings.size(), 1u);
122 EXPECT_intersections_valid(x_squash_neg, seg, xings, 1e-12);
124 rev.reset(x_squash_neg.reverse());
125 xings = rev->intersect(seg);
126 EXPECT_EQ(xings.size(), 1u);
127 EXPECT_intersections_valid(*rev, seg, xings, 1e-12);
131 EllipticalArc y_squash_pos{{0.0, -2.0}, {3.0, 2.0}, 0,
true,
true, {0.0, 2.0}};
132 EllipticalArc y_squash_neg{{0.0, -2.0}, {3.0, 2.0}, 0,
true,
false, {0.0, 2.0}};
133 auto const squash_to_y =
Scale(0.0, 1.0);
134 y_squash_pos *= squash_to_y;
135 y_squash_neg *= squash_to_y;
137 for (
size_t _ = 0; _ < 10'000; _++) {
138 auto seg =
LineSegment(
Point(g_random_double_range(-3.0, -1.0), g_random_double_range(-2.0, 2.0)),
139 Point(g_random_double_range(1.0, 3.0), g_random_double_range(-2.0, 2.0)));
140 auto xings = y_squash_pos.intersect(seg, 1e-10);
141 EXPECT_EQ(xings.size(), 1u);
142 EXPECT_intersections_valid(y_squash_pos, seg, xings, 1e-12);
144 std::unique_ptr<Curve> rev{y_squash_pos.reverse()};
145 xings = rev->intersect(seg, 1e-12);
146 EXPECT_EQ(xings.size(), 1u);
147 EXPECT_intersections_valid(*rev, seg, xings, 1e-12);
149 xings = y_squash_neg.intersect(seg, 1e-12);
150 EXPECT_EQ(xings.size(), 1u);
151 EXPECT_intersections_valid(y_squash_neg, seg, xings, 1e-12);
153 rev.reset(y_squash_neg.reverse());
154 xings = rev->intersect(seg, 1e-12);
155 EXPECT_EQ(xings.size(), 1u);
156 EXPECT_intersections_valid(*rev, seg, xings, 1e-12);
162 Point const from{1, 0};
163 Point const to{0.30901699437494745, 0.9510565162951535};
167 ASSERT_EQ(xings.
size(), 1);
168 EXPECT_TRUE(
are_near(xings[0].point(), to, 1e-12));
169 EXPECT_TRUE(
are_near(xings[0].first, 1.0, 1e-24));
170 EXPECT_TRUE(
are_near(xings[0].second, 1.0, 1e-24));
174 ASSERT_EQ(xings.
size(), 1);
175 EXPECT_TRUE(
are_near(xings[0].point(), from, 1e-12));
176 EXPECT_TRUE(
are_near(xings[0].first, 0.0, 1e-24));
177 EXPECT_TRUE(
are_near(xings[0].second, 1.0, 1e-24));
181TEST(EllipticalArcTest, ArcIntersection) {
182 std::vector<CurveIntersection> r1, r2;
187 EXPECT_EQ(r1.size(), 2u);
188 EXPECT_intersections_valid(a1, a2, r1, 1e-10);
193 EXPECT_EQ(r2.size(), 3u);
194 EXPECT_intersections_valid(a3, a4, r2, 1e-10);
198 auto self_intersect = upper.
intersect(upper);
199 EXPECT_EQ(self_intersect.size(), 2u);
203 auto quartering_overlap_xings = right.
intersect(upper);
204 EXPECT_EQ(quartering_overlap_xings.size(), 2u);
208 EXPECT_EQ(middle.
intersect(upper).size(), 2u);
213 EXPECT_EQ(arc1.intersect(arc2).size(), 0u);
218 EXPECT_EQ(eccentric.intersect(subarc).size(), 2u);
222 auto expected_neg_x = upper.
intersect(lower);
223 ASSERT_EQ(expected_neg_x.size(), 1);
224 auto const &left_pt = expected_neg_x[0];
225 EXPECT_EQ(left_pt.point(),
Point(-1, 0));
226 EXPECT_DOUBLE_EQ(left_pt.first, 1.0);
227 EXPECT_DOUBLE_EQ(left_pt.second, 0.0);