Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to curve balloon tail (simple triangle shape)

I have a simple triangular shape (that serves as a balloon tail) which I'm trying to curve like the following:

enter image description here

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?

like image 646
Ser Pounce Avatar asked Apr 17 '14 22:04

Ser Pounce


3 Answers

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.

like image 190
Warren Dew Avatar answered Nov 14 '22 22:11

Warren Dew


@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.

enter image description here

like image 38
Satachito Avatar answered Nov 14 '22 21:11

Satachito


I would first experiment with PaintCode to see what kind of code and variables I can come up with.

like image 1
Rivera Avatar answered Nov 14 '22 22:11

Rivera