Advertisement
BurningBunny

Warp GraphicsPath along a Bézier Spline

Aug 1st, 2013
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.31 KB | None | 0 0
  1. /*
  2.  *
  3.  * Transform GraphicsPath points along a cubic Bézier Spline
  4.  *  http://csharpcodewhisperer.blogspot.com
  5.  *    
  6.  *
  7.  * Made using SharpDevelop
  8.  *
  9.  *
  10.  */
  11. GraphicsPath BezierWarp(GraphicsPath text,Size size)
  12. {
  13.     // Control points for a cubic Bézier spline
  14.     PointF P0 = new PointF();
  15.     PointF P1 = new PointF();
  16.     PointF P2 = new PointF();
  17.     PointF P3 = new PointF();
  18.    
  19.     float shrink = 20;
  20.     float shift = 0;
  21.    
  22.     P0.X = shrink;
  23.     P0.Y = shrink+shift;
  24.     P1.X = size.Width-shrink;
  25.     P1.Y = shrink;
  26.     P2.X = shrink;
  27.     P2.Y = size.Height-shrink;
  28.     P3.X = size.Width-shrink;
  29.     P3.Y = size.Height-shrink-shift;
  30.  
  31.     // Calculate coefficients A thru H from the control points
  32.     float A = P3.X - 3 * P2.X + 3 * P1.X - P0.X;
  33.     float B = 3 * P2.X - 6 * P1.X + 3 * P0.X;
  34.     float C = 3 * P1.X - 3 * P0.X;
  35.     float D = P0.X;
  36.  
  37.     float E = P3.Y - 3 * P2.Y + 3 * P1.Y - P0.Y;
  38.     float F = 3 * P2.Y - 6 * P1.Y + 3 * P0.Y;
  39.     float G = 3 * P1.Y - 3 * P0.Y;
  40.     float H = P0.Y;
  41.  
  42.     PointF[] pathPoints = text.PathPoints;
  43.     RectangleF textBounds = text.GetBounds();
  44.    
  45.     for (int i =0; i < pathPoints.Length; i++)
  46.     {
  47.         PointF pt = pathPoints[i];
  48.         float textX = pt.X;
  49.         float textY = pt.Y;
  50.        
  51.         // Normalize the x coordinate into the parameterized value
  52.         // with a domain between 0 and 1.
  53.         float t  =  textX / textBounds.Width;
  54.         float t2 = (t * t);
  55.         float t3 = (t * t * t);
  56.        
  57.         // Calculate spline point for parameter t
  58.         float Sx = A * t3 + B * t2 + C * t + D;
  59.         float Sy = E * t3 + F * t2 + G * t + H;
  60.        
  61.         // Calculate the tangent vector for the point
  62.         float Tx = 3 * A * t2 + 2 * B * t + C;
  63.         float Ty = 3 * E * t2 + 2 * F * t + G;
  64.         // Rotate 90 or 270 degrees to make it a perpendicular
  65.         float Px = - Ty;
  66.         float Py =   Tx;
  67.        
  68.         // Normalize the perpendicular into a unit vector
  69.         float magnitude = (float)Math.Sqrt((Px*Px) + (Py*Py));
  70.         Px /= magnitude;
  71.         Py /= magnitude;
  72.        
  73.         // Assume that input text point y coord is the "height" or
  74.         // distance from the spline. Multiply the perpendicular vector
  75.         // with y. It becomes the new magnitude of the vector.
  76.         Px *= textY;
  77.         Py *= textY;
  78.        
  79.         // Translate the spline point using the resultant vector
  80.         float finalX = Px + Sx;
  81.         float finalY = Py + Sy;
  82.        
  83.         pathPoints[i] = new PointF(finalX, finalY);
  84.     }
  85.    
  86.     return new GraphicsPath(pathPoints,text.PathTypes);
  87. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement