Skip to content

Commit 4cd46ae

Browse files
Merge pull request #1072 from Geode-solutions/feat/add-ellipse-basic-object-ditance-and-intersection
feat(Ellipse): add ellipse basic object and function to compute intersections and distances with ellipse
2 parents 79e7ebc + f7ec133 commit 4cd46ae

File tree

10 files changed

+1008
-19
lines changed

10 files changed

+1008
-19
lines changed
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* Copyright (c) 2019 - 2025 Geode-solutions
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*
22+
*/
23+
24+
#pragma once
25+
26+
#include <geode/geometry/common.hpp>
27+
#include <geode/geometry/frame.hpp>
28+
29+
namespace geode
30+
{
31+
FORWARD_DECLARATION_DIMENSION_CLASS( OwnerEllipse );
32+
FORWARD_DECLARATION_DIMENSION_CLASS( Point );
33+
FORWARD_DECLARATION_DIMENSION_CLASS( Frame );
34+
35+
template < index_t dimension >
36+
using RefPoint = std::reference_wrapper< const Point< dimension > >;
37+
ALIAS_2D_AND_3D( RefPoint );
38+
template < index_t dimension >
39+
using RefFrame = std::reference_wrapper< const Frame< dimension > >;
40+
ALIAS_2D_AND_3D( RefFrame );
41+
} // namespace geode
42+
43+
namespace geode
44+
{
45+
template < typename PointType, typename FrameType, index_t dimension >
46+
class GenericEllipse
47+
{
48+
public:
49+
GenericEllipse( PointType center, FrameType axis );
50+
51+
GenericEllipse(
52+
const GenericEllipse< PointType, FrameType, dimension >& other );
53+
GenericEllipse< PointType, FrameType, dimension >& operator=(
54+
const GenericEllipse< PointType, FrameType, dimension >& other );
55+
GenericEllipse( GenericEllipse< PointType, FrameType, dimension >&&
56+
other ) noexcept;
57+
GenericEllipse< PointType, FrameType, dimension >& operator=(
58+
GenericEllipse< PointType, FrameType, dimension >&&
59+
other ) noexcept;
60+
61+
[[nodiscard]] const Point< dimension >& center() const;
62+
[[nodiscard]] const Frame< dimension >& axes() const;
63+
64+
private:
65+
PointType center_;
66+
FrameType axes_;
67+
};
68+
69+
template < index_t dimension >
70+
class OwnerEllipse : public GenericEllipse< Point< dimension >,
71+
Frame< dimension >,
72+
dimension >
73+
{
74+
using Base =
75+
GenericEllipse< Point< dimension >, Frame< dimension >, dimension >;
76+
77+
public:
78+
explicit OwnerEllipse(
79+
Point< dimension > center, Frame< dimension > axes );
80+
81+
OwnerEllipse( const OwnerEllipse< dimension >& other );
82+
OwnerEllipse< dimension >& operator=(
83+
const OwnerEllipse< dimension >& other );
84+
OwnerEllipse( OwnerEllipse< dimension >&& other ) noexcept;
85+
OwnerEllipse< dimension >& operator=(
86+
OwnerEllipse< dimension >&& other ) noexcept;
87+
};
88+
ALIAS_2D_AND_3D( OwnerEllipse );
89+
90+
template < index_t dimension >
91+
class Ellipse : public GenericEllipse< RefPoint< dimension >,
92+
RefFrame< dimension >,
93+
dimension >
94+
{
95+
using Base = GenericEllipse< RefPoint< dimension >,
96+
RefFrame< dimension >,
97+
dimension >;
98+
99+
public:
100+
Ellipse(
101+
const Point< dimension >& center, const Frame< dimension >& axes );
102+
Ellipse( const Ellipse< dimension >& other );
103+
Ellipse( const OwnerEllipse< dimension >& other );
104+
Ellipse< dimension >& operator=( const Ellipse< dimension >& other );
105+
Ellipse( Ellipse< dimension >&& other ) noexcept;
106+
Ellipse< dimension >& operator=(
107+
Ellipse< dimension >&& other ) noexcept;
108+
};
109+
ALIAS_2D_AND_3D( Ellipse );
110+
} // namespace geode

include/geode/geometry/distance.hpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,12 @@ namespace geode
3434
FORWARD_DECLARATION_DIMENSION_CLASS( Segment );
3535
FORWARD_DECLARATION_DIMENSION_CLASS( Triangle );
3636
FORWARD_DECLARATION_DIMENSION_CLASS( Sphere );
37+
FORWARD_DECLARATION_DIMENSION_CLASS( Ellipse );
3738
ALIAS_2D_AND_3D( Point );
3839
ALIAS_2D_AND_3D( Triangle );
3940
ALIAS_2D_AND_3D( InfiniteLine );
4041
ALIAS_3D( Segment );
42+
ALIAS_2D_AND_3D( Ellipse );
4143
class Plane;
4244
class Tetrahedron;
4345
class Circle;
@@ -259,4 +261,15 @@ namespace geode
259261
*/
260262
[[nodiscard]] std::tuple< double, Point3D > opengeode_geometry_api
261263
point_disk_distance( const Point3D& point, const Disk& disk );
264+
265+
/*!
266+
* Compute the smallest distance between a point and an ellipse
267+
* @return a tuple containing:
268+
* - the smallest distance.
269+
* - the closest point on the ellipse.
270+
*/
271+
template < index_t dimension >
272+
[[nodiscard]] std::tuple< double, Point< dimension > >
273+
point_ellipse_distance( const Point< dimension >& point,
274+
const Ellipse< dimension >& ellipse );
262275
} // namespace geode

include/geode/geometry/intersection.hpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,15 @@ namespace geode
3737
FORWARD_DECLARATION_DIMENSION_CLASS( Segment );
3838
FORWARD_DECLARATION_DIMENSION_CLASS( Sphere );
3939
FORWARD_DECLARATION_DIMENSION_CLASS( Triangle );
40+
FORWARD_DECLARATION_DIMENSION_CLASS( Ellipse );
41+
FORWARD_DECLARATION_DIMENSION_CLASS( OwnerEllipse );
4042
ALIAS_2D_AND_3D( InfiniteLine );
4143
ALIAS_2D_AND_3D( OwnerInfiniteLine );
4244
ALIAS_2D_AND_3D( Point );
4345
ALIAS_2D_AND_3D( Segment );
4446
ALIAS_3D( Triangle );
47+
ALIAS_2D_AND_3D( Ellipse );
48+
ALIAS_1D_AND_2D_AND_3D( OwnerEllipse );
4549
class Circle;
4650
class Cylinder;
4751
class Plane;
@@ -228,4 +232,27 @@ namespace geode
228232
[[nodiscard]] IntersectionResult< OwnerInfiniteLine3D >
229233
opengeode_geometry_api plane_plane_intersection(
230234
const Plane& plane0, const Plane& plane1 );
235+
236+
/*!
237+
* Compute the intersection between a segment and an ellipse
238+
* @return an optional of the intersection points.
239+
*/
240+
template < index_t dimension >
241+
[[nodiscard]] IntersectionResult<
242+
absl::InlinedVector< Point< dimension >, 2 > >
243+
opengeode_geometry_api segment_ellipse_intersection(
244+
const Segment< dimension >& segment,
245+
const Ellipse< dimension >& ellipse );
246+
247+
/*!
248+
* Compute the intersection between a line and an ellipse
249+
* @return an optional of the intersection points.
250+
*/
251+
template < index_t dimension >
252+
[[nodiscard]] IntersectionResult<
253+
absl::InlinedVector< Point< dimension >, 2 > >
254+
opengeode_geometry_api line_ellipse_intersection(
255+
const InfiniteLine< dimension >& line,
256+
const Ellipse< dimension >& ellipse );
257+
231258
} // namespace geode

src/geode/geometry/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ add_geode_library(
2626
"barycentric_coordinates.cpp"
2727
"basic_objects/circle.cpp"
2828
"basic_objects/cylinder.cpp"
29+
"basic_objects/ellipse.cpp"
2930
"basic_objects/infinite_line.cpp"
3031
"basic_objects/plane.cpp"
3132
"basic_objects/polygon.cpp"
@@ -61,6 +62,7 @@ add_geode_library(
6162
"barycentric_coordinates.hpp"
6263
"basic_objects/circle.hpp"
6364
"basic_objects/cylinder.hpp"
65+
"basic_objects/ellipse.hpp"
6466
"basic_objects/infinite_line.hpp"
6567
"basic_objects/plane.hpp"
6668
"basic_objects/polygon.hpp"
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* Copyright (c) 2019 - 2025 Geode-solutions
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*
22+
*/
23+
24+
#include <geode/geometry/basic_objects/ellipse.hpp>
25+
26+
namespace geode
27+
{
28+
template < typename PointType, typename FrameType, index_t dimension >
29+
GenericEllipse< PointType, FrameType, dimension >::GenericEllipse(
30+
PointType center, FrameType axes )
31+
: center_( std::move( center ) ), axes_( std::move( axes ) )
32+
{
33+
}
34+
template < typename PointType, typename FrameType, index_t dimension >
35+
GenericEllipse< PointType, FrameType, dimension >::GenericEllipse(
36+
const GenericEllipse< PointType, FrameType, dimension >& ) = default;
37+
template < typename PointType, typename FrameType, index_t dimension >
38+
GenericEllipse< PointType, FrameType, dimension >&
39+
GenericEllipse< PointType, FrameType, dimension >::operator=(
40+
const GenericEllipse< PointType, FrameType, dimension >& ) =
41+
default;
42+
template < typename PointType, typename FrameType, index_t dimension >
43+
GenericEllipse< PointType, FrameType, dimension >::GenericEllipse(
44+
GenericEllipse< PointType, FrameType, dimension >&& ) noexcept =
45+
default;
46+
47+
template < typename PointType, typename FrameType, index_t dimension >
48+
GenericEllipse< PointType, FrameType, dimension >&
49+
GenericEllipse< PointType, FrameType, dimension >::operator=(
50+
GenericEllipse< PointType, FrameType, dimension >&& ) noexcept =
51+
default;
52+
53+
template < typename PointType, typename FrameType, index_t dimension >
54+
const Point< dimension >&
55+
GenericEllipse< PointType, FrameType, dimension >::center() const
56+
{
57+
return center_;
58+
}
59+
template < typename PointType, typename FrameType, index_t dimension >
60+
const Frame< dimension >&
61+
GenericEllipse< PointType, FrameType, dimension >::axes() const
62+
{
63+
return axes_;
64+
}
65+
66+
template < index_t dimension >
67+
OwnerEllipse< dimension >::OwnerEllipse(
68+
Point< dimension > center, Frame< dimension > axes )
69+
: Base( std::move( center ), std::move( axes ) )
70+
{
71+
}
72+
template < index_t dimension >
73+
OwnerEllipse< dimension >::OwnerEllipse(
74+
const OwnerEllipse< dimension >& ) = default;
75+
template < index_t dimension >
76+
OwnerEllipse< dimension >& OwnerEllipse< dimension >::operator=(
77+
const OwnerEllipse< dimension >& ) = default;
78+
template < index_t dimension >
79+
OwnerEllipse< dimension >::OwnerEllipse(
80+
OwnerEllipse< dimension >&& ) noexcept = default;
81+
template < index_t dimension >
82+
OwnerEllipse< dimension >& OwnerEllipse< dimension >::operator=(
83+
OwnerEllipse< dimension >&& ) noexcept = default;
84+
85+
template < index_t dimension >
86+
Ellipse< dimension >::Ellipse(
87+
const Point< dimension >& center, const Frame< dimension >& axes )
88+
: Base( center, axes )
89+
{
90+
}
91+
template < index_t dimension >
92+
Ellipse< dimension >::Ellipse( const Ellipse< dimension >& ) = default;
93+
template < index_t dimension >
94+
Ellipse< dimension >::Ellipse( const OwnerEllipse< dimension >& other )
95+
: Base( other.center(), other.axes() )
96+
{
97+
}
98+
template < index_t dimension >
99+
Ellipse< dimension >& Ellipse< dimension >::operator=(
100+
const Ellipse< dimension >& ) = default;
101+
template < index_t dimension >
102+
Ellipse< dimension >::Ellipse( Ellipse< dimension >&& ) noexcept = default;
103+
template < index_t dimension >
104+
Ellipse< dimension >& Ellipse< dimension >::operator=(
105+
Ellipse< dimension >&& ) noexcept = default;
106+
107+
template class opengeode_geometry_api
108+
GenericEllipse< Point< 2 >, Frame< 2 >, 2 >;
109+
template class opengeode_geometry_api
110+
GenericEllipse< Point< 3 >, Frame< 3 >, 3 >;
111+
template class opengeode_geometry_api
112+
GenericEllipse< RefPoint< 2 >, RefFrame< 2 >, 2 >;
113+
template class opengeode_geometry_api
114+
GenericEllipse< RefPoint< 3 >, RefFrame< 3 >, 3 >;
115+
template class opengeode_geometry_api OwnerEllipse< 2 >;
116+
template class opengeode_geometry_api OwnerEllipse< 3 >;
117+
template class opengeode_geometry_api Ellipse< 2 >;
118+
template class opengeode_geometry_api Ellipse< 3 >;
119+
} // namespace geode

src/geode/geometry/basic_objects/sphere.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,9 @@ namespace geode
6363
BoundingBox< dimension >
6464
GenericSphere< PointType, dimension >::bounding_box() const
6565
{
66-
Point< dimension > translation;
67-
for( const auto i : LRange{ dimension } )
68-
{
69-
translation.set_value( i, radius_ );
70-
}
7166
BoundingBox< dimension > bbox;
72-
const Point< dimension >& origin = origin_;
73-
bbox.add_point( origin + translation );
74-
bbox.add_point( origin - translation );
67+
bbox.add_point( origin_ );
68+
bbox.extends( radius_ );
7569
return bbox;
7670
}
7771

0 commit comments

Comments
 (0)