I have a simple triangular shape (that serves as a balloon tail) which I'm trying to curve like the following:
I have the tail shape stored in a CGMutablePathRef
and it's drawn as follows:
- (void) drawPaths
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextAddPath(context, self.mutablePath);
CGPathRelease(mutablePath);
CGColorRelease(fillColor);
CGColorRelease(strokeColor);
}
I am trying to make it so when I input some angle to this algorithm (say 45 degrees) that the tail rotates and curves much like the above photo. The rotation is obviously an easy transformation, but getting it to curve is what I'm struggling with. I realize that I probably need to use: CGPathAddQuadCurveToPoint
however I'm having trouble understanding what to set as my control points and am getting unpredictable results. Even this brilliant post has left me clueless: Given a CGPath, how to make it curve?
Does anyone know how to do this?
I assume you have or can get the x and y coordinates for both the origin point of the paths - the end of the paths on the balloon - and for the end point - the tip of the triangle - that you want for each of the paths. Let's call the origin point (xorig, yorig) and the end point (xend, yend). To make the path curve, we need to calculate a reasonable quadratic curve coordination point, which we'll call (xc, yc). I believe the following coordinate calculation will produce a reasonable curve for you:
xc = (xorig * 3 + xend) / 4;
yc = (xorig + xend) / 2;
CGPathAddQuadCurveToPoint(mutablePath, NULL, xc, yc, xend, yend).
To make the path curve differently, you can vary the weights of xorig and xend in the calculation of xc.
@interface V : UIView @end @implementation V { UIBezierPath* u1; UIBezierPath* u2; } - (void) awakeFromNib { u1 = UIBezierPath.bezierPath; [ u1 moveToPoint:CGPointMake( 0, 0 ) ]; [ u1 addQuadCurveToPoint:CGPointMake( 10, 100 ) controlPoint:CGPointMake( 10, 30 ) ]; [ u1 addQuadCurveToPoint:CGPointMake( 20, 0 ) controlPoint:CGPointMake( 10, 30 ) ]; u1.lineWidth = 3; u1.lineJoinStyle = kCGLineJoinBevel; u2 = UIBezierPath.bezierPath; [ u2 moveToPoint:CGPointMake( 0, 0 ) ]; [ u2 addQuadCurveToPoint:CGPointMake( 50, 60 ) controlPoint:CGPointMake( 10, 30 ) ]; [ u2 addQuadCurveToPoint:CGPointMake( 20, 0 ) controlPoint:CGPointMake( 10, 30 ) ]; u2.lineWidth = 3; u2.lineJoinStyle = kCGLineJoinBevel; } - (void) drawRect:(CGRect)p { CGContextTranslateCTM( UIGraphicsGetCurrentContext(), 100, 100 ); [ u1 stroke ]; CGContextTranslateCTM( UIGraphicsGetCurrentContext(), 100, 0 ); [ u2 stroke ]; } @end
This program results image following. Maybe some hints.
I would first experiment with PaintCode to see what kind of code and variables I can come up with.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With