diff --git a/tdcgal/plane/objects.py b/tdcgal/plane/objects.py index d9880cc..d7192fb 100644 --- a/tdcgal/plane/objects.py +++ b/tdcgal/plane/objects.py @@ -114,7 +114,20 @@ class Ray2D(Shape2D, Ray_2): @property def source(self) -> Point2D: return self._source() + + # 返回射线方向 + @property + def direction(self) -> Direction2D: + return self._direction() + # 重载`repr`方法,返回Ray2D的字符串表示 + def __repr__(self) -> str: + return f"Ray2D({self.source}, {self.direction})" + + # 重载`in`运算符,判断点是否在射线上 + def __contains__(self, point: [Tuple[float, float], Point2D]) -> bool: + point = point_maker(point) + return self.has_on(point) class Direction2D(Shape2D, Direction_2): diff --git a/tdcgal/plane/plane.cpp b/tdcgal/plane/plane.cpp index 88c80ba..124abc1 100644 --- a/tdcgal/plane/plane.cpp +++ b/tdcgal/plane/plane.cpp @@ -9,13 +9,17 @@ typedef CGAL::Simple_cartesian Kernel; typedef Kernel::Point_2 Point_2; typedef Kernel::Segment_2 Segment_2; typedef Kernel::Line_2 Line_2; +typedef Kernel::Direction_2 Direction_2; +typedef Kernel::Vector_2 Vector_2; +typedef Kernel::Ray_2 Ray_2; +typedef Kernel::FT FT; -namespace py = pybind11; - -double squared_distance(const Point_2 &a, const Point_2 &b) { +template FT squared_distance(const T &a, const U &b) { return CGAL::squared_distance(a, b); } +namespace py = pybind11; + void init_plane(py::module_ &m) { py::class_(m, "Point_2") .def(py::init()) @@ -24,31 +28,110 @@ void init_plane(py::module_ &m) { .def("hx", &Point_2::hx) .def("hy", &Point_2::hy) .def("hw", &Point_2::hw) - .def(py::self == py::self) - .def("__repr__", [](const Point_2 &a) { - return ""; - }); + .def( + "squared_distance", + [](const Point_2 &a, const Point_2 &b) { + return CGAL::squared_distance(a, b); + }, + "返回两个点的平方距离") + .def(py::self == py::self); py::class_(m, "Segment_2") .def(py::init()) .def("_source", &Segment_2::source) .def("_target", &Segment_2::target) .def("min", &Segment_2::min, "返回线段的端点中较小的那个") .def("max", &Segment_2::max, "返回线段的端点中较大的那个") - .def("squared_length", &Segment_2::squared_length, "返回线段的平方长度") + .def("_squared_length", &Segment_2::squared_length, "返回线段的平方长度") .def("opposite", &Segment_2::opposite, "返回反向的线段") - .def("has_on", &Segment_2::collinear_has_on, "判断点是否在线段上") - .def("supporting_line", &Segment_2::supporting_line, "返回与线段共线的直线") + .def("has_on", &Segment_2::has_on, "判断点是否在线段上") + .def("supporting_line", &Segment_2::supporting_line, + "返回与线段共线的直线") .def("is_degenerate", &Segment_2::is_degenerate, "判断线段端点是否重合") .def("is_horizontal", &Segment_2::is_horizontal, "判断线段是否水平") .def("is_vertical", &Segment_2::is_vertical, "判断线段是否垂直") .def(py::self == py::self) .def(py::self != py::self); - py::class_(m, "Line_2") + py::class_(m, "Ray_2") .def(py::init()) - .def("a", &Line_2::a) - .def("b", &Line_2::b) - .def("c", &Line_2::c) - .def(py::self == py::self); - m.def("squared_distance", &squared_distance); + .def(py::init()) + .def(py::init()) + .def(py::init()) + .def("_source", &Ray_2::source) + .def("_direction", &Ray_2::direction) + .def("has_on", &Ray_2::has_on, "判断点是否在射线上") + .def( + "point", [](const Ray_2 &r, FT i) { return r.point(i); }, + "返回射线上任意一点, 根据`i`值返回射线`r`上的某一点, i=0返回起点, " + "i>=0") + .def("supporting_line", &Ray_2::supporting_line, "返回与射线共线的直线") + .def("opposite", &Ray_2::opposite, "返回起点相同但反向的射线") + .def("is_degenerate", &Ray_2::is_degenerate, "判断射线是否退化") + .def("is_horizontal", &Ray_2::is_horizontal, "判断射线是否水平") + .def("is_vertical", &Ray_2::is_vertical, "判断射线是否垂直") + .def(py::self == py::self) + .def(py::self != py::self); + py::class_(m, "Line_2") + .def(py::init()) + .def(py::init()) + .def(py::init()) + .def(py::init()) + .def(py::init()) + .def(py::init()) + .def("_a", &Line_2::a) + .def("_b", &Line_2::b) + .def("_c", &Line_2::c) + .def("x_at_y", &Line_2::x_at_y, "返回给定y值处的x值") + .def("y_at_x", &Line_2::y_at_x, "返回给定x值处的y值") + .def( + "point", [](const Line_2 &l, FT i) { return l.point(i); }, + "根据`i`值返回直线`l`上的某一点, i=0返回起点, i>=0") + .def("direction", &Line_2::direction, "返回直线的方向") + .def("to_vector", &Line_2::to_vector, "返回直线的方向向量") + .def("opposite", &Line_2::opposite, "返回反向的直线") + .def("has_on", &Line_2::has_on, "判断点是否在直线上") + .def("has_on_positive_side", &Line_2::has_on_positive_side, + "判断点是否在直线的正方向上") + .def("has_on_negative_side", &Line_2::has_on_negative_side, + "判断点是否在直线的负方向上") + .def("projection", &Line_2::projection, "返回点到直线的正交投影") + .def("perpendicular", &Line_2::perpendicular, "返回与直线垂直的直线") + .def("transform", &Line_2::transform, "返回经过变换后的直线") + .def("is_degenerate", &Line_2::is_degenerate, "判断直线是否退化") + .def("is_horizontal", &Line_2::is_horizontal, "判断直线是否水平") + .def("is_vertical", &Line_2::is_vertical, "判断直线是否垂直") + .def(py::self == py::self) + .def(py::self != py::self); + + m.def("squared_distance", &squared_distance, + "返回两个点的平方距离"); + m.def("squared_distance", &squared_distance, + "返回点到线段的平方距离"); + m.def("squared_distance", &squared_distance, + "返回点到射线的平方距离"); + m.def("squared_distance", &squared_distance, + "返回点到直线的平方距离"); + m.def("squared_distance", &squared_distance, + "返回线段到点的平方距离"); + m.def("squared_distance", &squared_distance, + "返回线段到线段的平方距离"); + m.def("squared_distance", &squared_distance, + "返回线段到射线的平方距离"); + m.def("squared_distance", &squared_distance, + "返回线段到直线的平方距离"); + m.def("squared_distance", &squared_distance, + "返回射线到点的平方距离"); + m.def("squared_distance", &squared_distance, + "返回射线到线段的平方距离"); + m.def("squared_distance", &squared_distance, + "返回射线到射线的平方距离"); + m.def("squared_distance", &squared_distance, + "返回射线到直线的平方距离"); + m.def("squared_distance", &squared_distance, + "返回直线到点的平方距离"); + m.def("squared_distance", &squared_distance, + "返回直线到线段的平方距离"); + m.def("squared_distance", &squared_distance, + "返回直线到射线的平方距离"); + m.def("squared_distance", &squared_distance, + "返回直线到直线的平方距离"); };