Skip to content

Commit 9dc1016

Browse files
scpeterscaguero
authored andcommitted
Line2: use T instead of double in APIs (#809)
1. Set with Vector2 parameters: Verified setting start/end points using Vector2 instances. 2. CrossProduct: Added explicit tests for both Line2 and Vector2 cross products. Expect CrossProduct of parallel lines is 0. 3. OnSegment and Within: Tested points on segment, collinear points outside bounds, non-collinear points within bounding box, and endpoints. 4. Intersect Branch Coverage: • Parallel collinear non-overlapping line segments. • Collinear lines where only the second endpoint lies on the segment. • Line extensions that intersect outside X or Y bounding ranges. • Intersect overload taking no output point. 5. Operators: Expanded operator== and operator!= self-comparison checks. 6. Template Types: Added test cases for Line2i (int) and Line2f (float). Assisted-by: Gemini 3.6 Flash Signed-off-by: Steve Peters <scpeters@intrinsic.ai> (cherry picked from commit 59ed16c)
1 parent 59cc2c2 commit 9dc1016

2 files changed

Lines changed: 17 additions & 16 deletions

File tree

include/gz/math/Line2.hh

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ namespace gz::math
4545
/// \param[in] _y1 Y coordinate of the start point.
4646
/// \param[in] _x2 X coordinate of the end point.
4747
/// \param[in] _y2 Y coordinate of the end point.
48-
public: Line2(double _x1, double _y1, double _x2, double _y2)
48+
public: Line2(T _x1, T _y1, T _x2, T _y2)
4949
{
5050
this->Set(_x1, _y1, _x2, _y2);
5151
}
@@ -65,10 +65,10 @@ namespace gz::math
6565
/// \param[in] _y1 Y coordinate of the start point.
6666
/// \param[in] _x2 X coordinate of the end point.
6767
/// \param[in] _y2 Y coordinate of the end point.
68-
public: void Set(double _x1, double _y1, double _x2, double _y2)
68+
public: void Set(T _x1, T _y1, T _x2, T _y2)
6969
{
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));
70+
this->pts[0].Set(_x1, _y1);
71+
this->pts[1].Set(_x2, _y2);
7272
}
7373

7474
/// \brief Return the cross product of this line and the given line.
@@ -77,7 +77,7 @@ namespace gz::math
7777
/// (a.start.y - a.end.y) * (b.start.x - b.end.x)
7878
/// \param[in] _line Line for the cross product computation.
7979
/// \return Return the cross product of this line and the given line.
80-
public: double CrossProduct(const Line2<T> &_line) const
80+
public: T CrossProduct(const Line2<T> &_line) const
8181
{
8282
return (this->pts[0].X() - this->pts[1].X()) *
8383
(_line[0].Y() -_line[1].Y()) -
@@ -90,7 +90,7 @@ namespace gz::math
9090
// (_pt.y - a.y) * (b.x - a.x) - (_pt.x - a.x) * (b.y - a.y)
9191
/// \param[in] _pt Point for the cross product computation.
9292
/// \return Return the cross product of this line and the given point.
93-
public: double CrossProduct(const Vector2<T> &_pt) const
93+
public: T CrossProduct(const Vector2<T> &_pt) const
9494
{
9595
return (_pt.Y() - this->pts[0].Y()) *
9696
(this->pts[1].X() - this->pts[0].X()) -
@@ -108,7 +108,7 @@ namespace gz::math
108108
double _epsilon = 1e-6) const
109109
{
110110
return math::equal(this->CrossProduct(_pt),
111-
0., _epsilon);
111+
static_cast<T>(0), static_cast<T>(_epsilon));
112112
}
113113

114114
/// \brief Check if the given line is parallel with this line.
@@ -122,7 +122,7 @@ namespace gz::math
122122
double _epsilon = 1e-6) const
123123
{
124124
return math::equal(this->CrossProduct(_line),
125-
0., _epsilon);
125+
static_cast<T>(0), static_cast<T>(_epsilon));
126126
}
127127

128128
/// \brief Check if the given line is collinear with this line. This
@@ -160,14 +160,15 @@ namespace gz::math
160160
public: bool Within(const math::Vector2<T> &_pt,
161161
double _epsilon = 1e-6) const
162162
{
163+
auto eps = static_cast<T>(_epsilon);
163164
return _pt.X() <= std::max(this->pts[0].X(),
164-
this->pts[1].X()) + _epsilon &&
165+
this->pts[1].X()) + eps &&
165166
_pt.X() >= std::min(this->pts[0].X(),
166-
this->pts[1].X()) - _epsilon &&
167+
this->pts[1].X()) - eps &&
167168
_pt.Y() <= std::max(this->pts[0].Y(),
168-
this->pts[1].Y()) + _epsilon &&
169+
this->pts[1].Y()) + eps &&
169170
_pt.Y() >= std::min(this->pts[0].Y(),
170-
this->pts[1].Y()) - _epsilon;
171+
this->pts[1].Y()) - eps;
171172
}
172173

173174
/// \brief Check if this line intersects the given line segment.
@@ -193,11 +194,11 @@ namespace gz::math
193194
public: bool Intersect(const Line2<T> &_line, math::Vector2<T> &_pt,
194195
double _epsilon = 1e-6) const
195196
{
196-
double d = this->CrossProduct(_line);
197+
T d = this->CrossProduct(_line);
197198

198199
// d is zero if the two line are collinear. Must check special
199200
// cases.
200-
if (math::equal(d, 0.0, _epsilon))
201+
if (math::equal(d, static_cast<T>(0), static_cast<T>(_epsilon)))
201202
{
202203
// Check if _line's starting point is on the line.
203204
if (this->Within(_line[0], _epsilon))

src/python_pybind11/src/Line2.hh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,15 @@ void helpDefineMathLine2(py::module &m, const std::string &typestr)
5656
py::dynamic_attr())
5757
.def(py::init<const gz::math::Vector2<T>&,
5858
const gz::math::Vector2<T>&>())
59-
.def(py::init<double, double, double, double>())
59+
.def(py::init<T, T, T, T>())
6060
.def(py::self != py::self)
6161
.def(py::self == py::self)
6262
.def("set",
6363
py::overload_cast<const gz::math::Vector2<T>&,
6464
const gz::math::Vector2<T>&>(&Class::Set),
6565
"Set the start and end point of the line segment")
6666
.def("set",
67-
py::overload_cast<double, double, double, double>(&Class::Set),
67+
py::overload_cast<T, T, T, T>(&Class::Set),
6868
"Set the start and end point of the line segment")
6969
.def("cross_product",
7070
py::overload_cast<const Class&>(&Class::CrossProduct, py::const_),

0 commit comments

Comments
 (0)