Skip to content

Commit 7df3819

Browse files
authored
Merge branch 'main' into scpeters/filter_more_test_coverage
2 parents b9e3ee1 + 268039c commit 7df3819

10 files changed

Lines changed: 332 additions & 35 deletions

File tree

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name: Bazel repeat flaky tests
2+
on:
3+
schedule:
4+
# GitHub caches are purged after 7 days of inactivity, so
5+
# running twice a week helps protect the bazel cache
6+
# Run at 16:00 UTC, Monday and Friday
7+
- cron: '0 16 * * 1,5'
8+
9+
jobs:
10+
repeat-flaky-tests:
11+
uses: ./.github/workflows/bazel_repeat_tests.yml
12+
with:
13+
flaky: 1
14+
runs_per_test: 10
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name: Bazel repeat non-flaky tests
2+
on:
3+
schedule:
4+
# GitHub caches are purged after 7 days of inactivity, so
5+
# running twice a week helps protect the bazel cache
6+
# Run at 17:00 UTC, Monday and Friday
7+
- cron: '0 17 * * 1,5'
8+
9+
jobs:
10+
repeat-non-flaky-tests:
11+
uses: ./.github/workflows/bazel_repeat_tests.yml
12+
with:
13+
flaky: 0
14+
runs_per_test: 10
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Bazel repeat tests
2+
on:
3+
workflow_call:
4+
inputs: &shared_inputs
5+
flaky:
6+
description: "0 to execute non-flaky tests, 1 to execute flaky tests"
7+
default: 0
8+
required: false
9+
type: string
10+
runs_per_test:
11+
description: "Number of times to repeat each test"
12+
default: 10
13+
required: false
14+
type: string
15+
workflow_dispatch:
16+
inputs: *shared_inputs
17+
18+
jobs:
19+
repeat-tests:
20+
uses: bazel-contrib/.github/.github/workflows/bazel.yaml@v7.7.0
21+
with:
22+
folders: |
23+
[
24+
"."
25+
]
26+
exclude: |
27+
[
28+
{"folder": ".", "bzlmodEnabled": false}
29+
]
30+
exclude_windows: true
31+
bazel_test_command: |
32+
# Exit with success code 0 if no targets match the query
33+
# `grep -q '^' fails if the query output is empty
34+
bazel query "attr(flaky, ${{ inputs.flaky }}, tests(//...))" \
35+
| grep -q '^' || exit 0
36+
bazel test --runs_per_test=${{ inputs.runs_per_test }} \
37+
--test_output=errors \
38+
$(bazel query "attr(flaky, ${{ inputs.flaky }}, tests(//...))")

include/gz/math/Line2.hh

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ namespace gz::math
6767
/// \param[in] _y2 Y coordinate of the end point.
6868
public: void Set(double _x1, double _y1, double _x2, double _y2)
6969
{
70-
this->pts[0].Set(_x1, _y1);
71-
this->pts[1].Set(_x2, _y2);
70+
this->pts[0].Set(static_cast<T>(_x1), static_cast<T>(_y1));
71+
this->pts[1].Set(static_cast<T>(_x2), static_cast<T>(_y2));
7272
}
7373

7474
/// \brief Return the cross product of this line and the given line.
@@ -253,10 +253,7 @@ namespace gz::math
253253
/// \return The length of the line.
254254
public: T Length() const
255255
{
256-
return sqrt((this->pts[0].X() - this->pts[1].X()) *
257-
(this->pts[0].X() - this->pts[1].X()) +
258-
(this->pts[0].Y() - this->pts[1].Y()) *
259-
(this->pts[0].Y() - this->pts[1].Y()));
256+
return static_cast<T>(this->pts[0].Distance(this->pts[1]));
260257
}
261258

262259
/// \brief Get the slope of the line

include/gz/math/Line3.hh

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ namespace gz::math
4848
/// \param[in] _y1 Y coordinate of the start point.
4949
/// \param[in] _x2 X coordinate of the end point.
5050
/// \param[in] _y2 Y coordinate of the end point.
51-
public: Line3(const double _x1, const double _y1,
52-
const double _x2, const double _y2)
51+
public: Line3(const T _x1, const T _y1,
52+
const T _x2, const T _y2)
5353
{
5454
this->Set(_x1, _y1, _x2, _y2);
5555
}
@@ -61,9 +61,9 @@ namespace gz::math
6161
/// \param[in] _x2 X coordinate of the end point.
6262
/// \param[in] _y2 Y coordinate of the end point.
6363
/// \param[in] _z2 Z coordinate of the end point.
64-
public: Line3(const double _x1, const double _y1,
65-
const double _z1, const double _x2,
66-
const double _y2, const double _z2)
64+
public: Line3(const T _x1, const T _y1,
65+
const T _z1, const T _x2,
66+
const T _y2, const T _z2)
6767
{
6868
this->Set(_x1, _y1, _z1, _x2, _y2, _z2);
6969
}
@@ -100,9 +100,9 @@ namespace gz::math
100100
/// \param[in] _y2 Y coordinate of the end point.
101101
/// \param[in] _z Z coordinate of both points,
102102
/// by default _z is set to 0.
103-
public: void Set(const double _x1, const double _y1,
104-
const double _x2, const double _y2,
105-
const double _z = 0)
103+
public: void Set(const T _x1, const T _y1,
104+
const T _x2, const T _y2,
105+
const T _z = 0)
106106
{
107107
this->pts[0].Set(_x1, _y1, _z);
108108
this->pts[1].Set(_x2, _y2, _z);
@@ -115,9 +115,9 @@ namespace gz::math
115115
/// \param[in] _x2 X coordinate of the end point.
116116
/// \param[in] _y2 Y coordinate of the end point.
117117
/// \param[in] _z2 Z coordinate of the end point.
118-
public: void Set(const double _x1, const double _y1,
119-
const double _z1, const double _x2,
120-
const double _y2, const double _z2)
118+
public: void Set(const T _x1, const T _y1,
119+
const T _z1, const T _x2,
120+
const T _y2, const T _z2)
121121
{
122122
this->pts[0].Set(_x1, _y1, _z1);
123123
this->pts[1].Set(_x2, _y2, _z2);
@@ -134,7 +134,7 @@ namespace gz::math
134134
/// \return The length of the line.
135135
public: T Length() const
136136
{
137-
return this->pts[0].Distance(this->pts[1]);
137+
return static_cast<T>(this->pts[0].Distance(this->pts[1]));
138138
}
139139

140140
/// \brief Get the shortest line between this line and the
@@ -214,7 +214,8 @@ namespace gz::math
214214
double mua = clamp(numer / denom, 0.0, 1.0);
215215
double mub = clamp((d1343 + d4321 * mua) / d4343, 0.0, 1.0);
216216

217-
_result.Set(this->pts[0] + (p21 * mua), _line[0] + (p43 * mub));
217+
_result.Set(this->pts[0] + (p21 * static_cast<T>(mua)),
218+
_line[0] + (p43 * static_cast<T>(mub)));
218219

219220
return true;
220221
}
@@ -229,13 +230,13 @@ namespace gz::math
229230
auto ptTo1 = _pt - this->pts[1];
230231

231232
// Point is projected beyond pt0 or the line has length 0
232-
if (ptTo0.Dot(line) <= 0.0)
233+
if (ptTo0.Dot(line) <= static_cast<T>(0))
233234
{
234235
return ptTo0.Length();
235236
}
236237

237238
// Point is projected beyond pt1
238-
if (ptTo1.Dot(line) >= 0.0)
239+
if (ptTo1.Dot(line) >= static_cast<T>(0))
239240
{
240241
return ptTo1.Length();
241242
}
@@ -341,18 +342,19 @@ namespace gz::math
341342
public: bool Within(const math::Vector3<T> &_pt,
342343
double _epsilon = 1e-6) const
343344
{
345+
auto eps = static_cast<T>(_epsilon);
344346
return _pt.X() <= std::max(this->pts[0].X(),
345-
this->pts[1].X()) + _epsilon &&
347+
this->pts[1].X()) + eps &&
346348
_pt.X() >= std::min(this->pts[0].X(),
347-
this->pts[1].X()) - _epsilon &&
349+
this->pts[1].X()) - eps &&
348350
_pt.Y() <= std::max(this->pts[0].Y(),
349-
this->pts[1].Y()) + _epsilon &&
351+
this->pts[1].Y()) + eps &&
350352
_pt.Y() >= std::min(this->pts[0].Y(),
351-
this->pts[1].Y()) - _epsilon &&
353+
this->pts[1].Y()) - eps &&
352354
_pt.Z() <= std::max(this->pts[0].Z(),
353-
this->pts[1].Z()) + _epsilon &&
355+
this->pts[1].Z()) + eps &&
354356
_pt.Z() >= std::min(this->pts[0].Z(),
355-
this->pts[1].Z()) - _epsilon;
357+
this->pts[1].Z()) - eps;
356358
}
357359

358360
/// \brief Equality operator.

src/Line2_TEST.cc

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,49 @@ TEST(Line2Test, Constructor)
4040
EXPECT_NO_THROW(lineB[2].X());
4141
EXPECT_DOUBLE_EQ(lineB[2].X(), lineB[1].X());
4242
EXPECT_NO_THROW(lineA[0].X());
43+
44+
// Test Set method with Vector2
45+
lineA.Set(math::Vector2d(5, 6), math::Vector2d(7, 8));
46+
EXPECT_EQ(lineA[0], math::Vector2d(5, 6));
47+
EXPECT_EQ(lineA[1], math::Vector2d(7, 8));
48+
}
49+
50+
/////////////////////////////////////////////////
51+
TEST(Line2Test, CrossProduct)
52+
{
53+
math::Line2d lineA(0, 0, 10, 0);
54+
math::Line2d lineB(0, 0, 0, 10);
55+
EXPECT_DOUBLE_EQ(lineA.CrossProduct(lineB), 100.0);
56+
57+
math::Vector2d pt(5, 5);
58+
EXPECT_DOUBLE_EQ(lineA.CrossProduct(pt), 50.0);
59+
}
60+
61+
/////////////////////////////////////////////////
62+
TEST(Line2Test, OnSegmentAndWithin)
63+
{
64+
math::Line2d line(0, 0, 10, 10);
65+
66+
// Point on segment
67+
math::Vector2d pt1(5, 5);
68+
EXPECT_TRUE(line.Within(pt1));
69+
EXPECT_TRUE(line.OnSegment(pt1));
70+
71+
// Point collinear with line, but outside segment bounds
72+
math::Vector2d pt2(15, 15);
73+
EXPECT_FALSE(line.Within(pt2));
74+
EXPECT_FALSE(line.OnSegment(pt2));
75+
76+
// Point within bounding box of segment, but not collinear
77+
math::Vector2d pt3(5, 6);
78+
EXPECT_TRUE(line.Within(pt3));
79+
EXPECT_FALSE(line.OnSegment(pt3));
80+
81+
// Endpoints
82+
EXPECT_TRUE(line.Within(line[0]));
83+
EXPECT_TRUE(line.OnSegment(line[0]));
84+
EXPECT_TRUE(line.Within(line[1]));
85+
EXPECT_TRUE(line.OnSegment(line[1]));
4386
}
4487

4588
/////////////////////////////////////////////////
@@ -83,29 +126,34 @@ TEST(Line2Test, ParallelLine)
83126
// Line is always parallel with itself
84127
math::Line2d line(0, 0, 10, 0);
85128
EXPECT_TRUE(line.Parallel(line, 1e-10));
129+
EXPECT_DOUBLE_EQ(line.CrossProduct(line), 0.0);
86130
}
87131

88132
{
89133
// Degenerate line segment
90134
// Still expect Line is parallel with itself
91135
math::Line2d line(0, 0, 0, 0);
92136
EXPECT_TRUE(line.Parallel(line, 1e-10));
137+
EXPECT_DOUBLE_EQ(line.CrossProduct(line), 0.0);
93138
}
94139

95140
math::Line2d lineA(0, 0, 10, 0);
96141
math::Line2d lineB(0, 0, 10, 0);
97142
EXPECT_TRUE(lineA.Parallel(lineB, 1e-10));
143+
EXPECT_DOUBLE_EQ(lineA.CrossProduct(lineB), 0.0);
98144

99145
lineB.Set(0, 0, 0, 10);
100146
EXPECT_FALSE(lineA.Parallel(lineB));
101147

102148
lineB.Set(0, 10, 10, 10);
103149
EXPECT_TRUE(lineA.Parallel(lineB));
150+
EXPECT_DOUBLE_EQ(lineA.CrossProduct(lineB), 0.0);
104151

105152
lineB.Set(0, 10, 10, 10.00001);
106153
EXPECT_FALSE(lineA.Parallel(lineB, 1e-10));
107154
EXPECT_FALSE(lineA.Parallel(lineB));
108155
EXPECT_TRUE(lineA.Parallel(lineB, 1e-3));
156+
EXPECT_NEAR(lineA.CrossProduct(lineB), 0.0, 1e-3);
109157
}
110158

111159
/////////////////////////////////////////////////
@@ -234,6 +282,28 @@ TEST(Line2Test, Intersect)
234282
lineB.Set(0, 10, 10, 0);
235283
EXPECT_TRUE(lineA.Intersect(lineB, pt));
236284
EXPECT_EQ(pt, math::Vector2d(5, 5));
285+
286+
// Collinear parallel non-overlapping lines
287+
lineA.Set(0, 0, 10, 0);
288+
lineB.Set(20, 0, 30, 0);
289+
EXPECT_FALSE(lineA.Intersect(lineB, pt));
290+
EXPECT_FALSE(lineA.Intersect(lineB));
291+
292+
// Collinear lines where lineB end point is within lineA but start point isn't
293+
lineA.Set(0, 0, 10, 0);
294+
lineB.Set(-5, 0, 5, 0);
295+
EXPECT_TRUE(lineA.Intersect(lineB, pt));
296+
EXPECT_EQ(pt, math::Vector2d(5, 0));
297+
298+
// Lines whose extensions intersect, but intersection Y is outside bounds
299+
lineA.Set(-10, 0, 10, 0);
300+
lineB.Set(0, 2, 0, 10);
301+
EXPECT_FALSE(lineA.Intersect(lineB, pt));
302+
303+
// Lines whose extensions intersect, but intersection X is outside bounds
304+
lineA.Set(0, -10, 0, 10);
305+
lineB.Set(2, 0, 10, 0);
306+
EXPECT_FALSE(lineA.Intersect(lineB, pt));
237307
}
238308

239309
/////////////////////////////////////////////////
@@ -243,7 +313,9 @@ TEST(Line2Test, Equality)
243313
math::Line2d lineB(1, 2, 2, 2);
244314

245315
EXPECT_TRUE(lineA != lineB);
316+
EXPECT_FALSE(lineA == lineB);
246317
EXPECT_TRUE(lineA == lineA);
318+
EXPECT_FALSE(lineA != lineA);
247319

248320
lineB.Set(1, 1, 2, 1.1);
249321
EXPECT_FALSE(lineA == lineB);
@@ -266,3 +338,18 @@ TEST(Line2Test, OperatorStreamOut)
266338
stream << line;
267339
EXPECT_EQ(stream.str(), "0 1 2 3");
268340
}
341+
342+
/////////////////////////////////////////////////
343+
TEST(Line2Test, TemplateTypes)
344+
{
345+
math::Line2i lineI(0, 0, 10, 10);
346+
EXPECT_EQ(lineI[0], math::Vector2i(0, 0));
347+
EXPECT_EQ(lineI[1], math::Vector2i(10, 10));
348+
EXPECT_EQ(lineI.Length(), 14);
349+
350+
math::Line2f lineF(0.0f, 0.0f, 10.0f, 10.0f);
351+
EXPECT_FLOAT_EQ(lineF[0].X(), 0.0f);
352+
EXPECT_FLOAT_EQ(lineF[1].Y(), 10.0f);
353+
EXPECT_NEAR(lineF.Length(), 14.1421356f, 1e-4f);
354+
}
355+

0 commit comments

Comments
 (0)