@@ -54,12 +54,12 @@ public static void FindParents<TParent1, TParent2>(DependencyObject currentObjec
5454 } while ( ( parent1 == default ( TParent1 ) ) || ( parent2 == default ( TParent2 ) ) ) ;
5555 }
5656
57- public static bool Intersect ( MyPoint a1 , MyPoint b1 , MyPoint a2 , MyPoint b2 )
57+ public static bool Intersect ( MyPoint a1 , MyPoint a2 , MyPoint b1 , MyPoint b2 )
5858 {
5959 bool par1 = a1 . X > b2 . X ; //второй перед первым
60- bool par2 = a2 . X > b1 . X ; //первый перед вторым
60+ bool par2 = b1 . X > a2 . X ; //первый перед вторым
6161 bool par3 = a1 . Y > b2 . Y ; //первый под вторым
62- bool par4 = a2 . Y > b1 . Y ; //второй под первым
62+ bool par4 = b1 . Y > a2 . Y ; //второй под первым
6363 //если хоть одно условие выполняется - прямоугольники не пересекаются
6464 return ! ( par1 || par2 || par3 || par4 ) ;
6565 }
@@ -73,7 +73,17 @@ public static MyPoint GetEndPointDiagonal(MyPoint a1, MyPoint b1)
7373 return new MyPoint ( Math . Max ( a1 . X , b1 . X ) , Math . Max ( a1 . Y , b1 . Y ) ) ;
7474 }
7575
76- //пока что не ясно
76+ #region Check on intersections curve Bezier and line
77+ // based on https://www.particleincell.com/2013/cubic-line-intersection/
78+ /*
79+ You can read more:
80+ https://github.com/w8r/bezier-intersect/blob/master/dist/bezier-intersect.js
81+ https://math.stackexchange.com/questions/2347733/intersections-between-a-cubic-b%C3%A9zier-curve-and-a-line
82+ https://math.stackexchange.com/questions/1337440/cubic-bezier-curve-and-a-straight-line-intersection/
83+ */
84+
85+
86+ //Gets coefficients of curve Bezier
7787 private static Point [ ] bezierCoeffs ( MyPoint bezierStartPoint , MyPoint bezierPoint1 , MyPoint bezierPoint2 , MyPoint bezierEndPoint )
7888 {
7989 Point [ ] coeffs = new Point [ 4 ] ;
@@ -97,7 +107,8 @@ private static Point[] bezierCoeffs(MyPoint bezierStartPoint, MyPoint bezierPoin
97107
98108 return coeffs ;
99109 }
100- //Поиск корней
110+
111+ //Find cubic roots
101112 private static double [ ] cubicRoots ( double a , double b , double c , double d )
102113 {
103114 double A = b / a ;
@@ -114,15 +125,21 @@ private static double[] cubicRoots(double a, double b, double c, double d)
114125
115126 if ( D >= 0 )
116127 {
117- double sqrtD = Math . Sqrt ( D ) ; //Это выражение используется несколько раз. Небольшая оптимизация
118- double _AD3 = - A / 3.0 ; //Это выражение используется несколько раз. Небольшая оптимизация
119- double RAsqrtD = R + sqrtD ; //Это выражение используется несколько раз. Небольшая оптимизация
120- double RSsqrtD = R - sqrtD ; //Это выражение используется несколько раз. Небольшая оптимизация
121- double D13 = ( 1.0 / 3.0 ) ; //Это выражение используется несколько раз. Небольшая оптимизация
128+ #region some optimization
129+
130+ double sqrtD = Math . Sqrt ( D ) ;
131+ double _AD3 = - A / 3.0 ;
132+ double RAsqrtD = R + sqrtD ;
133+ double RSsqrtD = R - sqrtD ;
134+ double D13 = ( 1.0 / 3.0 ) ;
135+
136+ #endregion some optimization
137+
122138 S = Math . Sign ( RAsqrtD ) * Math . Pow ( Math . Abs ( RAsqrtD ) , D13 ) ;
123139 T = Math . Sign ( RSsqrtD ) * Math . Pow ( Math . Abs ( RSsqrtD ) , D13 ) ;
124140
125- double SST = ( S + T ) ; //Это выражение используется несколько раз. Небольшая оптимизация
141+ //some optimization
142+ double SST = ( S + T ) ;
126143
127144 t [ 0 ] = _AD3 + SST ;
128145 t [ 1 ] = _AD3 - SST / 2.0 ;
@@ -137,12 +154,15 @@ private static double[] cubicRoots(double a, double b, double c, double d)
137154 }
138155 else
139156 {
157+
158+ #region some optimization
140159 double th = Math . Acos ( R / Math . Sqrt ( - Math . Pow ( Q , 3.0 ) ) ) ;
141- double sqrt_QM2 = 2.0 * Math . Sqrt ( - Q ) ; //Это выражение используется несколько раз. Небольшая оптимизация
142- double AD3 = A / 3.0 ; //Это выражение используется несколько раз. Небольшая оптимизация
160+ double sqrt_QM2 = 2.0 * Math . Sqrt ( - Q ) ;
161+ double AD3 = A / 3.0 ;
143162
144- double thD3 = ( th / 3.0 ) ; //Это выражение используется несколько раз. Небольшая оптимизация
145- double PIM2D3 = ( Math . PI * 2.0 ) / 3.0 ; //Это выражение используется несколько раз. Небольшая оптимизация
163+ double thD3 = ( th / 3.0 ) ;
164+ double PIM2D3 = ( Math . PI * 2.0 ) / 3.0 ;
165+ #endregion some optimization
146166
147167 t [ 0 ] = sqrt_QM2 * Math . Cos ( thD3 ) - AD3 ;
148168 t [ 1 ] = sqrt_QM2 * Math . Cos ( thD3 + PIM2D3 ) - AD3 ;
@@ -178,22 +198,27 @@ private static double[] cubicRoots(double a, double b, double c, double d)
178198 return sortSpecial ( t ) ;
179199 }
180200
181- //основная функция
201+ //Check on intersections curve Bezier and line
182202 public static bool ComputeIntersections ( MyPoint bezierStartPoint , MyPoint bezierPoint1 , MyPoint bezierPoint2 , MyPoint bezierEndPoint , MyPoint lineStartPoint , MyPoint lineEndPoint )
183203 {
204+
205+ // coefficients of line
184206 double A = lineEndPoint . Y - lineStartPoint . Y ; // A = y2 - y1
185207 double B = lineStartPoint . X - lineEndPoint . X ; // B = x1 - x2
186208 double C = - lineStartPoint . X * A - lineStartPoint . Y * B ; //C=x1*(y1-y2)+y1*(x2-x1) = x1*(-A)+y1*(-B)=-x1*(A)-y1*(B)
187209
210+ // coefficients of curve Bezier
188211 var coeffs = bezierCoeffs ( bezierStartPoint , bezierPoint1 , bezierPoint2 , bezierEndPoint ) ;
189212
190213 double [ ] P = new double [ 4 ] ;
191214
215+ // Transform cubic coefficients to line's coordinate system
192216 P [ 0 ] = A * coeffs [ 0 ] . X + B * coeffs [ 0 ] . Y ; // t^3
193217 P [ 1 ] = A * coeffs [ 1 ] . X + B * coeffs [ 1 ] . Y ; // t^2
194218 P [ 2 ] = A * coeffs [ 2 ] . X + B * coeffs [ 2 ] . Y ; // t
195219 P [ 3 ] = A * coeffs [ 3 ] . X + B * coeffs [ 3 ] . Y + C ;
196220
221+ //find roots of cubic
197222 var r = cubicRoots ( P [ 0 ] , P [ 1 ] , P [ 2 ] , P [ 3 ] ) ;
198223
199224 List < MyPoint > X = new List < MyPoint > ( ) ;
@@ -205,19 +230,24 @@ public static bool ComputeIntersections(MyPoint bezierStartPoint, MyPoint bezier
205230 for ( int i = 0 ; i < 3 ; i ++ )
206231 {
207232 t = r [ i ] ;
208- tMt = t * t ; //Это выражение используется несколько раз. Небольшая оптимизация
209- tMtMt = tMt * t ; //Это выражение используется несколько раз. Небольшая оптимизация
233+ #region some optimization
234+
235+ tMt = t * t ;
236+ tMtMt = tMt * t ;
237+
238+ #endregion some optimization
210239 p = new MyPoint
211240 (
212241 coeffs [ 0 ] . X * tMtMt + coeffs [ 1 ] . X * tMt + coeffs [ 2 ] . X * t + coeffs [ 3 ] . X ,
213242 coeffs [ 0 ] . Y * tMtMt + coeffs [ 1 ] . Y * tMt + coeffs [ 2 ] . Y * t + coeffs [ 3 ] . Y
214243 ) ;
215244
216- if ( ( lineEndPoint . X - lineStartPoint . X ) != 0 )
245+ if ( ( lineEndPoint . X - lineStartPoint . X ) != 0 ) // if not vertical line
217246 s = ( p . X - lineStartPoint . X ) / ( lineEndPoint . X - lineStartPoint . X ) ;
218247 else
219248 s = ( p . Y - lineStartPoint . Y ) / ( lineEndPoint . Y - lineStartPoint . Y ) ;
220249
250+ //check point in bounds
221251 if ( t < 0 || t > 1.0 || s < 0 || s > 1.0 )
222252 {
223253 continue ;
@@ -227,5 +257,6 @@ public static bool ComputeIntersections(MyPoint bezierStartPoint, MyPoint bezier
227257 }
228258 return X . Count > 0 ;
229259 }
260+ #endregion Check on intersections curve Bezier and line
230261 }
231262}
0 commit comments