Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
LineLineIntersection.cpp
Go to the documentation of this file.
1/* This file is part of MoDELib, the Mechanics Of Defects Evolution Library.
2 *
3 *
4 * MoDELib is distributed without any warranty under the
5 * GNU General Public License (GPL) v2 <http://www.gnu.org/licenses/>.
6 */
7
8#ifndef model_LineLineIntersection_CPP_
9#define model_LineLineIntersection_CPP_
10
11#include <cfloat>
12#include <tuple>
13#include <map>
14#include <stdexcept>
15#include <Eigen/Dense>
16
18
19namespace model
20{
21 /**********************************************************************/
22 template <int dim>
23 typename LineLineIntersection<dim>::SolutionType LineLineIntersection<dim>::findIntersections(const VectorDimD& A0,
24 const VectorDimD& D0,
25 const VectorDimD& A1,
26 const VectorDimD& D1)
27 {
46
47 const double normD0(D0.norm());
48 const double normD1(D1.norm());
49 if(normD0<FLT_EPSILON)
50 {
51 throw std::runtime_error("Norm of line direction D0 is close to singular. norm(D0)="+std::to_string(normD0)+"\n");
52 }
53 if(normD1<FLT_EPSILON)
54 {
55 throw std::runtime_error("Norm of line direction D1 is close to singular. norm(D1)="+std::to_string(normD1)+"\n");
56 }
57
58 const VectorDimD d0(D0/normD0);
59 const VectorDimD d1(D1/normD1);
60 const VectorDimD A0A1(A1-A0);
61
62 if(normD0<FLT_EPSILON && normD1<FLT_EPSILON)
63 {// both lines are degenerate
64 if(A0A1.squaredNorm()<FLT_EPSILON)
65 {
66 return std::make_tuple(INCIDENT,0.5*(A0+A1),0.5*(A0+A1),0.0,0.0);
67 }
68 else
69 {
70 return std::make_tuple(SKEW,A0,A1,0.0,0.0);
71 }
72 }
73 else if(normD0<FLT_EPSILON && normD1>=FLT_EPSILON)
74 {// line0 is degenerate
75 const double u1 = -A0A1.dot(d1);
76 const VectorDimD x(A1+u1*d1);
77 if((x-A0).squaredNorm()<FLT_EPSILON)
78 {
79 return std::make_tuple(INCIDENT,0.5*(A0+x),0.5*(A0+x),0.0,u1);
80 }
81 else
82 {
83 return std::make_tuple(SKEW,A0,x,0.0,u1);
84 }
85 }
86 else if(normD0>=FLT_EPSILON && normD1<FLT_EPSILON)
87 {// line1 is degenerate
88 const double u0 = A0A1.dot(d0);
89 const VectorDimD x(A0+u0*d0);
90 if((x-A1).squaredNorm()<FLT_EPSILON)
91 {
92 return std::make_tuple(INCIDENT,0.5*(A1+x),0.5*(A1+x),u0,0.0);
93 }
94 else
95 {
96 return std::make_tuple(SKEW,x,A1,u0,0.0);
97 }
98 }
99 else
100 {/* Both lines are non-degenerate. We search for the points x0 and x1
101 * that minimize the distance between the two lines:
102 * x0=A0+u0*d0
103 * x1=A1+u1*d1
104 * The scalar parameters u0 and u1 are found as
105 * [u0,u1]=argmin{1/2*(A0+u0*d0-A1-u1*d1)^2}
106 */
107 const double d0d1(d0.dot(d1));
108 const double det(1.0-d0d1*d0d1);
109 const double num0=d0.dot(A0A1)-d0d1*d1.dot(A0A1);
110 const double num1=d0d1*d0.dot(A0A1)-d1.dot(A0A1);
111 if(fabs(det)>FLT_EPSILON)
112 {
113 const double u0=num0/det;
114 const double u1=num1/det;
115 const VectorDimD x0(A0+u0*d0);
116 const VectorDimD x1(A1+u1*d1);
117 if((x0-x1).squaredNorm()<FLT_EPSILON)
118 {
119 return std::make_tuple(INCIDENT,x0,x1,u0,u1);
120 }
121 else
122 {
123 return std::make_tuple(SKEW,x0,x1,u0,u1);
124 }
125 }
126 else
127 {// A solution could not be found. This means parallel or coincident lines
128 const double A0A1norm(A0A1.norm());
129 if(A0A1norm<FLT_EPSILON) // this condition is unnecessary
130 {
131 return std::make_tuple(COINCIDENT,A0,A1,0.0,0.0);
132 }
133 else if(fabs(fabs(d0.dot(A0A1))-A0A1norm)<FLT_EPSILON)
134 {// coi
135 return std::make_tuple(COINCIDENT,A0,A1,0.0,0.0);
136 }
137 else
138 {
139 return std::make_tuple(PARALLEL,A0,A1,0.0,0.0);
140 }
141// if(fabs(num0)<FLT_EPSILON && fabs(num1)<FLT_EPSILON)
142// {
143// return std::make_tuple(COINCIDENT,0.5*(A0+A1),D0);
144// }
145// else
146// {// parallel segments
147//
148// return std::make_tuple(PARALLEL,A0,A1);
149// }
150 }
151
152 }
153 }
154
155 /**********************************************************************/
156 template<int dim>
158 const VectorDimD& D0,
159 const VectorDimD& A1,
160 const VectorDimD& D1) :
161 /* init */ sol(findIntersections(A0,D0,A1,D1))
162 /* init */,type(std::get<0>(sol))
163 /* init */,x0(std::get<1>(sol))
164 /* init */,x1(std::get<2>(sol))
165 /* init */,u0(std::get<3>(sol))
166 /* init */,u1(std::get<4>(sol))
167 {
168
169 }
170
171 template class LineLineIntersection<3>;
172 template class LineLineIntersection<2>;
173
174} /* namespace model */
175#endif
Eigen::Matrix< double, dim, 1 > VectorDimD
LineLineIntersection(const VectorDimD &A0, const VectorDimD &D0, const VectorDimD &A1, const VectorDimD &D1)
std::tuple< IntersectionType, VectorDimD, VectorDimD, double, double > SolutionType
const IntersectionType & type
x
Definition int_R.m:12
REAL det