1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
use crate;
use cratesat;
use crate;
/// Finds the best separating axis by testing edge-edge combinations between a cuboid and a segment (3D only).
///
/// In 3D, when a box collides with a line segment, the contact might occur along an axis
/// perpendicular to both a cuboid edge and the segment itself. This function tests all such
/// axes (cross products) to find the one with maximum separation.
///
/// # Parameters
///
/// - `cube1`: The cuboid
/// - `segment2`: The line segment
/// - `pos12`: The position of the segment relative to the cuboid
///
/// # Returns
///
/// A tuple containing:
/// - `Real`: The maximum separation found across all edge-edge axes
/// - **Positive**: Shapes are separated
/// - **Negative**: Shapes are overlapping
/// - `Vector`: The axis direction that gives this separation
///
/// # The 3 Axes Tested
///
/// A segment is a single edge, so we test cross products between:
/// - The segment's direction (B - A)
/// - Each of the 3 cuboid edge directions (X, Y, Z)
///
/// This gives 3 potential separating axes. The function delegates to
/// [`cuboid_support_map_find_local_separating_edge_twoway`](super::cuboid_support_map_find_local_separating_edge_twoway)
/// to perform the actual separation tests.
///
/// # Example
///
/// ```rust
/// # #[cfg(all(feature = "dim3", feature = "f32"))] {
/// use parry3d::shape::{Cuboid, Segment};
/// use parry3d::query::sat::cuboid_segment_find_local_separating_edge_twoway;
/// use parry3d::math::{Vector, Pose};
///
/// let cube = Cuboid::new(Vector::new(1.0, 1.0, 1.0));
/// let segment = Segment::new(
/// Vector::ZERO,
/// Vector::new(0.0, 2.0, 0.0)
/// );
///
/// // Position segment to the right of the cube
/// let pos12 = Pose::translation(2.5, 0.0, 0.0);
///
/// let (separation, axis) = cuboid_segment_find_local_separating_edge_twoway(
/// &cube,
/// &segment,
/// &pos12
/// );
///
/// println!("Edge-edge separation: {}", separation);
/// # }
/// ```
///
/// # Usage in Complete SAT
///
/// For a complete cuboid-segment collision test, you must also test:
/// 1. Cuboid face normals (X, Y, Z axes)
/// 2. Segment normal (in 2D) or face normal (for degenerate 3D cases)
/// 3. Edge-edge axes (this function, 3D only)
/// Finds the best separating axis by testing a segment's normal against a cuboid (2D only).
///
/// In 2D, a segment (line segment) has an associated normal vector perpendicular to the segment.
/// This function tests both directions of this normal to find the maximum separation from the cuboid.
///
/// # How It Works
///
/// The function treats the segment as a point-with-normal using one of its endpoints (point A)
/// and delegates to [`point_cuboid_find_local_separating_normal_oneway`](super::point_cuboid_find_local_separating_normal_oneway).
///
/// # Parameters
///
/// - `segment1`: The line segment whose normal will be tested
/// - `shape2`: The cuboid
/// - `pos12`: The position of the cuboid relative to the segment
///
/// # Returns
///
/// A tuple containing:
/// - `Real`: The separation distance along the segment's normal
/// - **Positive**: Shapes are separated
/// - **Negative**: Shapes are overlapping
/// - `Vector`: The normal direction that gives this separation
///
/// # Example
///
/// ```rust
/// # #[cfg(all(feature = "dim2", feature = "f32"))] {
/// use parry2d::shape::{Segment, Cuboid};
/// use parry2d::query::sat::segment_cuboid_find_local_separating_normal_oneway;
/// use parry2d::math::{Vector, Pose};
///
/// // Horizontal segment
/// let segment = Segment::new(
/// Vector::ZERO,
/// Vector::new(2.0, 0.0)
/// );
/// let cuboid = Cuboid::new(Vector::new(1.0, 1.0));
///
/// // Position cuboid above the segment
/// let pos12 = Pose::translation(1.0, 2.5);
///
/// let (separation, normal) = segment_cuboid_find_local_separating_normal_oneway(
/// &segment,
/// &cuboid,
/// &pos12
/// );
///
/// println!("Separation along segment normal: {}", separation);
/// # }
/// ```
///
/// # 2D Only
///
/// This function is only available in 2D. In 3D, segments don't have a unique normal direction
/// (there are infinitely many perpendicular directions), so edge-edge cross products are used
/// instead (see `cuboid_segment_find_local_separating_edge_twoway`).