diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 38340ac23..6bbe7e369 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -96,7 +96,6 @@ if (PYTHONLIBS_FOUND) GaussMarkovProcess_TEST Inertial_TEST Kmeans_TEST - Line2_TEST Line3_TEST MassMatrix3_TEST Material_TEST diff --git a/src/python_pybind11/CMakeLists.txt b/src/python_pybind11/CMakeLists.txt index c2c142169..2e90e339f 100644 --- a/src/python_pybind11/CMakeLists.txt +++ b/src/python_pybind11/CMakeLists.txt @@ -73,6 +73,7 @@ if (${pybind11_FOUND}) Angle_TEST Color_TEST Helpers_TEST + Line2_TEST Rand_TEST Vector2_TEST Vector3_TEST diff --git a/src/python_pybind11/src/Line2.hh b/src/python_pybind11/src/Line2.hh new file mode 100644 index 000000000..0bcb97b6b --- /dev/null +++ b/src/python_pybind11/src/Line2.hh @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2021 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + +#ifndef IGNITION_MATH_PYTHON__LINE2_HH_ +#define IGNITION_MATH_PYTHON__LINE2_HH_ + +#include + +#include +#include + +#include + +namespace py = pybind11; +using namespace pybind11::literals; + +namespace ignition +{ +namespace math +{ +namespace python +{ +/// Define a pybind11 wrapper for an ignition::math::Line2 +/** + * \param[in] module a pybind11 module to add the definition to + * \param[in] typestr name of the type used by Python + */ +template +void defineMathLine2(py::module &m, const std::string &typestr) +{ + using Class = ignition::math::Line2; + auto toString = [](const Class &si) { + std::stringstream stream; + stream << si; + return stream.str(); + }; + std::string pyclass_name = typestr; + py::class_(m, + pyclass_name.c_str(), + py::buffer_protocol(), + py::dynamic_attr()) + .def(py::init&, + const ignition::math::Vector2&>()) + .def(py::init()) + .def(py::self != py::self) + .def(py::self == py::self) + .def("set", + py::overload_cast&, + const ignition::math::Vector2&>(&Class::Set), + "Set the start and end point of the line segment") + .def("set", + py::overload_cast(&Class::Set), + "Set the start and end point of the line segment") + .def("cross_product", + py::overload_cast(&Class::CrossProduct, py::const_), + "Return the cross product of this line and the given line.") + .def("cross_product", + py::overload_cast&>( + &Class::CrossProduct, py::const_), + "Return the cross product of this line and the given line.") + .def("collinear", + py::overload_cast&, double>( + &Class::Collinear, py::const_), + py::arg("_pt") = ignition::math::Vector2::Zero, + py::arg("_epsilon") = 1e-6, + "Check if the given point is collinear with this line.") + .def("collinear", + py::overload_cast(&Class::Collinear, py::const_), + py::arg("_pt") = Class(0, 0, 0, 0), py::arg("_epsilon") = 1e-6, + "Check if the given point is collinear with this line.") + .def("parallel", + &Class::Parallel, + py::arg("_line") = Class(0, 0, 0, 0), py::arg("_epsilon") = 1e-6, + "Check if the given line is parallel with this line.") + .def("on_segment", + &Class::OnSegment, + "Return whether the given point is on this line segment.") + .def("within", + &Class::Within, + "Check if the given point is between the start and end " + "points of the line segment. This does not imply that the point is " + "on the segment.") + .def("intersect", + py::overload_cast< + const Class&, + ignition::math::Vector2&, + double>( + &Class::Intersect, py::const_), + py::arg("_line") = Class(0, 0, 0, 0), + py::arg("_pt") = ignition::math::Vector2::Zero, + py::arg("_epsilon") = 1e-6, + "Check if this line intersects the given line segment.") + .def("intersect", + py::overload_cast(&Class::Intersect, py::const_), + py::arg("_line") = Class(0, 0, 0, 0), py::arg("_epsilon") = 1e-6, + "Check if this line intersects the given line segment.") + .def("length", + &Class::Length, + "Get the length of the line") + .def("slope", + &Class::Slope, + "Get the slope of the line") + .def("__copy__", [](const Class &self) { + return Class(self); + }) + .def("__deepcopy__", [](const Class &self, py::dict) { + return Class(self); + }, "memo"_a) + .def("__getitem__", + py::overload_cast(&Class::operator[], py::const_)) + .def("__setitem__", + [](Class* vec, unsigned index, T val) { (*vec)[index] = val; }) + .def("__str__", toString) + .def("__repr__", toString); +} + +} // namespace python +} // namespace math +} // namespace ignition + +#endif // IGNITION_MATH_PYTHON__LINE2_HH_ diff --git a/src/python_pybind11/src/_ignition_math_pybind11.cc b/src/python_pybind11/src/_ignition_math_pybind11.cc index cd8a9451a..d4216157a 100644 --- a/src/python_pybind11/src/_ignition_math_pybind11.cc +++ b/src/python_pybind11/src/_ignition_math_pybind11.cc @@ -17,6 +17,7 @@ #include "Angle.hh" #include "Color.hh" #include "Helpers.hh" +#include "Line2.hh" #include "Rand.hh" #include "Vector2.hh" #include "Vector3.hh" @@ -47,4 +48,8 @@ PYBIND11_MODULE(math, m) ignition::math::python::defineMathVector4(m, "Vector4d"); ignition::math::python::defineMathVector4(m, "Vector4i"); ignition::math::python::defineMathVector4(m, "Vector4f"); + + ignition::math::python::defineMathLine2(m, "Line2i"); + ignition::math::python::defineMathLine2(m, "Line2d"); + ignition::math::python::defineMathLine2(m, "Line2f"); } diff --git a/src/python/Line2_TEST.py b/src/python_pybind11/test/Line2_TEST.py similarity index 100% rename from src/python/Line2_TEST.py rename to src/python_pybind11/test/Line2_TEST.py