@@ -257,6 +257,25 @@ public PathGradientBrushApplicator(
257257 return this . centerPixel ;
258258 }
259259
260+ if ( this . edges . Count == 3 )
261+ {
262+ if ( ! this . FindPointOnTriangle (
263+ this . edges [ 0 ] . Start ,
264+ this . edges [ 1 ] . Start ,
265+ this . edges [ 2 ] . Start ,
266+ point ,
267+ out float u ,
268+ out float v ) )
269+ {
270+ return this . transparentPixel ;
271+ }
272+
273+ Vector4 pointColor = ( ( 1 - u - v ) * this . edges [ 0 ] . StartColor ) + ( u * this . edges [ 0 ] . EndColor ) +
274+ ( v * this . edges [ 2 ] . StartColor ) ;
275+
276+ return new Color ( pointColor ) . ToPixel < TPixel > ( ) ;
277+ }
278+
260279 var direction = Vector2 . Normalize ( point - this . center ) ;
261280 PointF end = point + ( PointF ) ( direction * this . maxDistance ) ;
262281
@@ -301,6 +320,40 @@ public PathGradientBrushApplicator(
301320
302321 return closest ;
303322 }
323+
324+ private bool FindPointOnTriangle ( PointF v1 , PointF v2 , PointF v3 , PointF point , out float u , out float v )
325+ {
326+ Vector2 e1 = v2 - v1 ;
327+ Vector2 e2 = v3 - v2 ;
328+ Vector2 e3 = v1 - v3 ;
329+
330+ Vector2 pv1 = point - v1 ;
331+ Vector2 pv2 = point - v2 ;
332+ Vector2 pv3 = point - v3 ;
333+
334+ var d1 = Vector3 . Cross ( new Vector3 ( e1 . X , e1 . Y , 0 ) , new Vector3 ( pv1 . X , pv1 . Y , 0 ) ) ;
335+ var d2 = Vector3 . Cross ( new Vector3 ( e2 . X , e2 . Y , 0 ) , new Vector3 ( pv2 . X , pv2 . Y , 0 ) ) ;
336+ var d3 = Vector3 . Cross ( new Vector3 ( e3 . X , e3 . Y , 0 ) , new Vector3 ( pv3 . X , pv3 . Y , 0 ) ) ;
337+
338+ if ( Math . Sign ( Vector3 . Dot ( d1 , d2 ) ) != Math . Sign ( Vector3 . Dot ( d1 , d3 ) ) || Math . Sign ( Vector3 . Dot ( d1 , d2 ) ) != Math . Sign ( Vector3 . Dot ( d2 , d3 ) ) )
339+ {
340+ u = 0 ;
341+ v = 0 ;
342+ return false ;
343+ }
344+
345+ // From Real-Time Collision Detection
346+ // https://gamedev.stackexchange.com/questions/23743/whats-the-most-efficient-way-to-find-barycentric-coordinates
347+ float d00 = Vector2 . Dot ( e1 , e1 ) ;
348+ float d01 = Vector2 . Dot ( e1 , - e3 ) ;
349+ float d11 = Vector2 . Dot ( - e3 , - e3 ) ;
350+ float d20 = Vector2 . Dot ( pv1 , e1 ) ;
351+ float d21 = Vector2 . Dot ( pv1 , - e3 ) ;
352+ float denominator = ( d00 * d11 ) - ( d01 * d01 ) ;
353+ u = ( ( d11 * d20 ) - ( d01 * d21 ) ) / denominator ;
354+ v = ( ( d00 * d21 ) - ( d01 * d20 ) ) / denominator ;
355+ return true ;
356+ }
304357 }
305358 }
306359}
0 commit comments