23 T errorLimit = std::numeric_limits<T>::epsilon() * T( 20 ) )
25 const auto crossDir = cross( plane1.
n, plane2.
n );
27 if ( crossDir.lengthSq() < errorLimit * errorLimit )
31 const auto point = matrix.inverse() *
Vector3<T>( plane1.
d, plane2.
d, 0 );
33 return Line3<T>( point, crossDir.normalized() );
53std::optional<Vector3<T>>
intersection(
const Line3<T>& line1,
const Line3<T>& line2,
54 T errorLimit = std::numeric_limits<T>::epsilon() * T( 20 ) )
56 const auto crossDir = cross( line1.d, line2.d );
57 if ( crossDir.lengthSq() < errorLimit * errorLimit )
60 const auto p1 = dot( crossDir, line1.p );
61 const auto p2 = dot( crossDir, line2.p );
62 if ( std::abs( p1 - p2 ) >= errorLimit )
65 const auto n2 = cross( line2.d, crossDir );
66 const T den = dot( line1.d, n2 );
69 return line1.p + dot( ( line2.p - line1.p ), n2 ) / den * line1.d;
76 auto avec = segm1.b - segm1.a;
77 if ( cross( avec, segm2.a - segm1.a ) * cross( segm2.b - segm1.a, avec ) <= 0 )
79 auto bvec = segm2.b - segm2.a;
80 auto cda = cross( bvec, segm1.a - segm2.a );
81 auto cbd = cross( segm1.b - segm2.a, bvec );
84 return ( segm1.b * cda + segm1.a * cbd ) / ( cda + cbd );
132 const auto d11 = line1.d.lengthSq();
133 const auto d12 = dot( line1.d, line2.d );
134 const auto d22 = line2.d.lengthSq();
135 const auto det = d12 * d12 - d11 * d22;
139 return { line1.p, line2.project( line1.p ) };
142 const auto dp = line2.p - line1.p;
143 const auto x = dot( dp, line1.d ) / det;
144 const auto y = dot( dp, line2.d ) / det;
145 const auto a = d12 * y - d22 * x;
146 const auto b = d11 * y - d12 * x;
147 return { line1( a ), line2( b ) };
156 const auto d11 = ln.d.lengthSq();
157 const auto d12 = dot( ln.d, ls.dir() );
158 const auto d22 = ls.lengthSq();
159 const auto det = d12 * d12 - d11 * d22;
161 return { ln.project( ls.a ), ls.a };
163 const auto dp = ls.a - ln.p;
164 const auto x = dot( dp, ln.d ) / det;
165 const auto y = dot( dp, ls.dir() ) / det;
166 const auto b = d11 * y - d12 * x;
168 return { ln.project( ls.a ), ls.a };
170 return { ln.project( ls.b ), ls.b };
171 const auto a = d12 * y - d22 * x;
172 return { ln( a ), ls( b ) };
180 const auto dd = line.d.lengthSq();
184 res.b = box.getBoxClosestPointTo( res.a );
187 const auto rdd = 1 / dd;
189 T bestDistSq = std::numeric_limits<T>::max();
191 static constexpr int otherDir[3][2] = { { 1, 2 }, { 2, 0 }, { 0, 1 } };
192 for (
int iDir = 0; iDir < 3; ++iDir )
195 Vector3<T> q[4] = { box.min, box.min, box.min, box.min };
197 const int iDir1 = otherDir[iDir][0];
198 const int iDir2 = otherDir[iDir][1];
200 q[1][iDir2] = box.max[iDir2];
202 q[2][iDir1] = box.max[iDir1];
203 q[2][iDir2] = box.max[iDir2];
205 q[3][iDir1] = box.max[iDir1];
208 const auto e = box.max[iDir] - box.min[iDir];
209 const auto ee = e * e;
210 const auto db = line.d[iDir] * e;
211 const auto denom = dd * ee - db * db;
212 const bool par = denom <= 0;
213 const auto rdenom = par ? 0 : 1 / denom;
214 for (
int j = 0; j < 4; ++j )
220 cand.a[iDir] = q[j][iDir];
225 const auto s = q[j] - line.p;
226 const auto dt = dot( line.d, s );
227 const auto bt = s[iDir] * e;
230 const auto t = ( dt * ee - bt * db ) * rdenom;
231 assert( !std::isnan( t ) );
234 const auto u = ( t * db - bt ) / ee;
235 assert( !std::isnan( u ) );
239 cand.a = line( dt * rdd );
244 cand.a = line( ( db + dt ) * rdd );
246 cand.b[iDir] = box.max[iDir];
252 cand.b[iDir] += e * u;
255 const auto distSq = cand.
lengthSq();
256 if ( distSq < bestDistSq )
271 using T =
typename V::ValueType;
272 std::optional<std::pair<T,T>> res;
273 const auto p = line.p - sphere.
center;
274 const auto d = line.d;
275 const auto dd = dot( d, d );
276 const auto pd = dot( p, d );
277 const auto des4 =
sqr( pd ) - dd * ( dot( p, p ) -
sqr( sphere.
radius ) );
280 const auto sqrtDes4 = std::sqrt( des4 );
282 res->first = ( -sqrtDes4 - pd ) / dd;
283 res->second = ( sqrtDes4 - pd ) / dd;
std::optional< Line3< T > > intersection(const Plane3< T > &plane1, const Plane3< T > &plane2, T errorLimit=std::numeric_limits< T >::epsilon() *T(20))
Definition MRIntersection.h:22
std::optional< T > distanceSq(const Plane3< T > &plane1, const Plane3< T > &plane2, T errorLimit=std::numeric_limits< T >::epsilon() *T(20))
Definition MRIntersection.h:90
std::optional< T > distance(const Plane3< T > &plane1, const Plane3< T > &plane2, T errorLimit=std::numeric_limits< T >::epsilon() *T(20))
Definition MRIntersection.h:104