@@ -400,6 +400,22 @@ private float GetMirrorHeight(float height)
400400 return height ;
401401 }
402402
403+ /// <summary>
404+ /// Flips a coordinate value to the other side of the screen and ensure it doesn't exceed the maximum value
405+ /// </summary>
406+ /// <param name="enabled">Flip coordinate enabled</param>
407+ /// <param name="screenDimension">Dimension of screen in axis to be flipped</param>
408+ /// <param name="coordinate">Coordinate in axis to be flipped</param>
409+ /// <returns>New coordinate in axis</returns>
410+ private float FlipCoord ( bool enabled , float screenDimension , float coordinate )
411+ {
412+ var max = Math . Max ( 0 , Math . Min ( coordinate , screenDimension ) ) ;
413+ return enabled ? screenDimension - max : max ;
414+ // Note: By camping these values, it ensures the resulting bezier curve when smoothed
415+ // never goes below 0 however, it does mean that it is not as smooth, as some values
416+ // may be smoothed to be negative based on the expected gradient
417+ }
418+
403419 /// <summary>
404420 /// Draw picture, Wave mode, Box variant
405421 /// </summary>
@@ -417,81 +433,78 @@ private float GetMirrorHeight(float height)
417433 {
418434 var step = ( direction < DrawingDirection . LeftRight ? width : height ) / ( sample . Length - 1 ) ;
419435 var path = new SKPath ( ) ;
436+ var flipImage = false ;
437+ var pointsArray = new ( float x , float y ) [ sample . Length ] ;
438+ var gradientsList = new float [ sample . Length ] ;
420439 switch ( direction )
421440 {
422- case DrawingDirection . TopBottom :
423- path . MoveTo ( x , y + height * sample [ 0 ] - ( Configuration . Current . Filling ? 0 : Configuration . Current . LinesThickness / 2 ) ) ;
424- for ( var i = 0 ; i < sample . Length - 1 ; i ++ )
441+ case DrawingDirection . TopBottom or DrawingDirection . BottomTop :
442+ flipImage = direction == DrawingDirection . TopBottom ;
443+ // Create a list of point of where the the curve must pass through
444+ for ( var i = 0 ; i < sample . Length ; i ++ )
425445 {
426- path . CubicTo (
427- x + step * ( i + 0.5f ) ,
428- y + height * sample [ i ] - ( Configuration . Current . Filling ? 0 : Configuration . Current . LinesThickness / 2 ) ,
429- x + step * ( i + 0.5f ) ,
430- y + height * sample [ i + 1 ] - ( Configuration . Current . Filling ? 0 : Configuration . Current . LinesThickness / 2 ) ,
431- x + step * ( i + 1 ) ,
432- y + height * sample [ i + 1 ] - ( Configuration . Current . Filling ? 0 : Configuration . Current . LinesThickness / 2 ) ) ;
446+ pointsArray [ i ] = ( step * i , height * ( 1 - sample [ i ] ) ) ;
433447 }
434- if ( Configuration . Current . Filling )
448+ // Calculate gradient between the two neighbouring points for every point
449+ for ( var i = 0 ; i < pointsArray . Length ; i ++ )
435450 {
436- path . LineTo ( x + width , y ) ;
437- path . LineTo ( x , y ) ;
438- path . Close ( ) ;
451+ // Determine the previous and next point
452+ // If there isn't one, use the current point
453+ var previousPoint = pointsArray [ Math . Max ( i - 1 , 0 ) ] ;
454+ var nextPoint = pointsArray [ Math . Min ( i + 1 , pointsArray . Length - 1 ) ] ;
455+ var gradient = nextPoint . y - previousPoint . y ;
456+ // If using the current point (when at the edges)
457+ // then the run in rise/run = 1, otherwise a two step run exists
458+ gradientsList [ i ] = i == 0 || i == pointsArray . Length - 1 ? gradient : gradient / 2 ;
439459 }
440- break ;
441- case DrawingDirection . BottomTop :
442- path . MoveTo ( x , y + height * ( 1 - sample [ 0 ] ) + ( Configuration . Current . Filling ? 0 : Configuration . Current . LinesThickness / 2 ) ) ;
443- for ( var i = 0 ; i < sample . Length - 1 ; i ++ )
460+ var yOffset = y + ( Configuration . Current . Filling ? 0 : Configuration . Current . LinesThickness / 2 ) ;
461+ path . MoveTo ( x + pointsArray [ 0 ] . x , yOffset + FlipCoord ( flipImage , height , pointsArray [ 0 ] . y ) ) ;
462+ for ( var i = 0 ; i < pointsArray . Length - 1 ; i ++ )
444463 {
445464 path . CubicTo (
446- x + step * ( i + 0.5f ) ,
447- y + height * ( 1 - sample [ i ] ) + ( Configuration . Current . Filling ? 0 : Configuration . Current . LinesThickness / 2 ) ,
448- x + step * ( i + 0.5f ) ,
449- y + height * ( 1 - sample [ i + 1 ] ) + ( Configuration . Current . Filling ? 0 : Configuration . Current . LinesThickness / 2 ) ,
450- x + step * ( i + 1 ) ,
451- y + height * ( 1 - sample [ i + 1 ] ) + ( Configuration . Current . Filling ? 0 : Configuration . Current . LinesThickness / 2 ) ) ;
465+ x + pointsArray [ i ] . x + step * 0.5f ,
466+ yOffset + FlipCoord ( flipImage , height , pointsArray [ i ] . y + gradientsList [ i ] * 0.5f ) ,
467+ x + pointsArray [ i + 1 ] . x + step * - 0.5f ,
468+ yOffset + FlipCoord ( flipImage , height , pointsArray [ i + 1 ] . y + gradientsList [ i + 1 ] * - 0.5f ) ,
469+ x + pointsArray [ i + 1 ] . x ,
470+ yOffset + FlipCoord ( flipImage , height , pointsArray [ i + 1 ] . y ) ) ;
452471 }
453472 if ( Configuration . Current . Filling )
454473 {
455- path . LineTo ( x + width , y + height ) ;
456- path . LineTo ( x , y + height ) ;
474+ path . LineTo ( x + width , y + FlipCoord ( flipImage , height , height ) ) ;
475+ path . LineTo ( x , y + FlipCoord ( flipImage , height , height ) ) ;
457476 path . Close ( ) ;
458477 }
459478 break ;
460- case DrawingDirection . LeftRight :
461- path . MoveTo ( x + width * sample [ 0 ] - ( Configuration . Current . Filling ? 0 : Configuration . Current . LinesThickness / 2 ) , y ) ;
462- for ( var i = 0 ; i < sample . Length - 1 ; i ++ )
479+ case DrawingDirection . LeftRight or DrawingDirection . RightLeft :
480+ flipImage = direction == DrawingDirection . RightLeft ;
481+ for ( var i = 0 ; i < sample . Length ; i ++ )
463482 {
464- path . CubicTo (
465- x + width * sample [ i ] - ( Configuration . Current . Filling ? 0 : Configuration . Current . LinesThickness / 2 ) ,
466- y + step * ( i + 0.5f ) ,
467- x + width * sample [ i + 1 ] - ( Configuration . Current . Filling ? 0 : Configuration . Current . LinesThickness / 2 ) ,
468- y + step * ( i + 0.5f ) ,
469- x + width * sample [ i + 1 ] - ( Configuration . Current . Filling ? 0 : Configuration . Current . LinesThickness / 2 ) ,
470- y + step * ( i + 1 ) ) ;
483+ pointsArray [ i ] = ( width * sample [ i ] , step * i ) ;
471484 }
472- if ( Configuration . Current . Filling )
485+ for ( var i = 0 ; i < pointsArray . Length ; i ++ )
473486 {
474- path . LineTo ( x , y + height ) ;
475- path . LineTo ( x , y ) ;
476- path . Close ( ) ;
487+ var previousPoint = pointsArray [ Math . Max ( i - 1 , 0 ) ] ;
488+ var nextPoint = pointsArray [ Math . Min ( i + 1 , pointsArray . Length - 1 ) ] ;
489+ var gradient = nextPoint . x - previousPoint . x ;
490+ gradientsList [ i ] = i == 0 || i == pointsArray . Length - 1 ? gradient : gradient / 2 ;
477491 }
478- break ;
479- case DrawingDirection . RightLeft :
480- path . MoveTo ( x + width * ( 1 - sample [ 0 ] ) + ( Configuration . Current . Filling ? 0 : Configuration . Current . LinesThickness / 2 ) , y ) ;
481- for ( var i = 0 ; i < sample . Length - 1 ; i ++ )
492+ var xOffset = x - ( Configuration . Current . Filling ? 0 : Configuration . Current . LinesThickness / 2 ) ;
493+ path . MoveTo ( xOffset + FlipCoord ( flipImage , width , pointsArray [ 0 ] . x ) , y + pointsArray [ 0 ] . y ) ;
494+ for ( var i = 0 ; i < pointsArray . Length - 1 ; i ++ )
482495 {
483496 path . CubicTo (
484- x + width * ( 1 - sample [ i ] ) + ( Configuration . Current . Filling ? 0 : Configuration . Current . LinesThickness / 2 ) ,
485- y + step * ( i + 0.5f ) ,
486- x + width * ( 1 - sample [ i + 1 ] ) + ( Configuration . Current . Filling ? 0 : Configuration . Current . LinesThickness / 2 ) ,
487- y + step * ( i + 0.5f ) ,
488- x + width * ( 1 - sample [ i + 1 ] ) + ( Configuration . Current . Filling ? 0 : Configuration . Current . LinesThickness / 2 ) ,
489- y + step * ( i + 1 ) ) ;
497+ xOffset + FlipCoord ( flipImage , width , pointsArray [ i ] . x + gradientsList [ i ] * 0.5f ) ,
498+ y + pointsArray [ i ] . y + step * 0.5f ,
499+ xOffset + FlipCoord ( flipImage , width , pointsArray [ i + 1 ] . x + gradientsList [ i + 1 ] * - 0.5f ) ,
500+ y + pointsArray [ i + 1 ] . y + step * - 0.5f ,
501+ xOffset + FlipCoord ( flipImage , width , pointsArray [ i + 1 ] . x ) ,
502+ y + pointsArray [ i + 1 ] . y ) ;
490503 }
491504 if ( Configuration . Current . Filling )
492505 {
493- path . LineTo ( x + width , y + height ) ;
494- path . LineTo ( x + width , y ) ;
506+ path . LineTo ( x + FlipCoord ( flipImage , width , 0 ) , y + height ) ;
507+ path . LineTo ( x + FlipCoord ( flipImage , width , 0 ) , y ) ;
495508 path . Close ( ) ;
496509 }
497510 break ;
0 commit comments