I'm trying to draw squiggle in Set Card Game. The output is not even close to what I want. How should I improve the drawing?
..
#define SQUIGGLE_CURVE_FACTOR 0.5
- (UIBezierPath *)drawSquiggleAtPoint:(CGPoint)point
{
CGFloat dx = self.bounds.size.width * SYMBOL_WIDTH_RATIO / 2;
CGFloat dy = self.bounds.size.height * SYMBOL_HEIGHT_RATIO / 2;
UIBezierPath *path = [[UIBezierPath alloc] init];
CGFloat dsqx = dx * SQUIGGLE_CURVE_FACTOR;
CGFloat dsqy = dy * SQUIGGLE_CURVE_FACTOR;
[path moveToPoint:CGPointMake(point.x - dx, point.y)];
[path addQuadCurveToPoint:CGPointMake(point.x - dsqx, point.y + dsqy) controlPoint:CGPointMake(point.x - dx, point.y + dy + dsqy)];
[path addCurveToPoint:CGPointMake(point.x + dx, point.y) controlPoint1:point controlPoint2:CGPointMake(point.x + dx, point.y + dy * 2)];
[path addQuadCurveToPoint:CGPointMake(point.x + dsqx, point.y - dsqy) controlPoint:CGPointMake(point.x + dx, point.y - dy - dsqy)];
[path addCurveToPoint:CGPointMake(point.x - dx, point.y) controlPoint1:point controlPoint2:CGPointMake(point.x - dx, point.y - dy * 2)];
return path;
}
- (UIBezierPath *)drawSquiggleAtPoint:(CGPoint)point
{
CGSize size = CGSizeMake(self.bounds.size.width * SYMBOL_WIDTH_RATIO, self.bounds.size.height * SYMBOL_HEIGHT_RATIO);
UIBezierPath *path = [[UIBezierPath alloc] init];
[path moveToPoint:CGPointMake(104, 15)];
[path addCurveToPoint:CGPointMake(63, 54) controlPoint1:CGPointMake(112.4, 36.9) controlPoint2:CGPointMake(89.7, 60.8)];
[path addCurveToPoint:CGPointMake(27, 53) controlPoint1:CGPointMake(52.3, 51.3) controlPoint2:CGPointMake(42.2, 42)];
[path addCurveToPoint:CGPointMake(5, 40) controlPoint1:CGPointMake(9.6, 65.6) controlPoint2:CGPointMake(5.4, 58.3)];
[path addCurveToPoint:CGPointMake(36, 12) controlPoint1:CGPointMake(4.6, 22) controlPoint2:CGPointMake(19.1, 9.7)];
[path addCurveToPoint:CGPointMake(89, 14) controlPoint1:CGPointMake(59.2, 15.2) controlPoint2:CGPointMake(61.9, 31.5)];
[path addCurveToPoint:CGPointMake(104, 15) controlPoint1:CGPointMake(95.3, 10) controlPoint2:CGPointMake(100.9, 6.9)];
[path applyTransform:CGAffineTransformMakeScale(0.9524*size.width/100, 0.9524*size.height/50)];
[path applyTransform:CGAffineTransformMakeTranslation(point.x - size.width/2 - 3 * size.width /100, point.y - size.height/2 - 8 * size.height/50)];
return path;
}
Here's some code that generates a fairly decent rendition of a squiggle
- (void)drawSquiggle
{
CGContextRef context = UIGraphicsGetCurrentContext();
// translate and scale the squiggle
CGContextSaveGState( context );
CGContextTranslateCTM( context, 0, 100 );
CGContextScaleCTM( context, 2.0, 2.0 );
// create the squiggle path
CGContextMoveToPoint( context, 104.0, 15.0 );
CGContextAddCurveToPoint( context, 112.4 , 36.9, 89.7, 60.8, 63.0, 54.0 );
CGContextAddCurveToPoint( context, 52.3 , 51.3, 42.2, 42.0, 27.0, 53.0 );
CGContextAddCurveToPoint( context, 9.6 , 65.6, 5.4, 58.3, 5.0, 40.0 );
CGContextAddCurveToPoint( context, 4.6 , 22.0, 19.1, 9.7, 36.0, 12.0 );
CGContextAddCurveToPoint( context, 59.2 , 15.2, 61.9, 31.5, 89.0, 14.0 );
CGContextAddCurveToPoint( context, 95.3 , 10.0, 100.9, 6.9, 104.0, 15.0 );
// draw the squiggle
CGContextSetLineCap( context, kCGLineCapRound );
CGContextSetLineWidth( context, 2.0 );
CGContextStrokePath( context );
// restore the graphics state
CGContextRestoreGState( context );
}
This is what it produces
Scaling and Translating the Squiggle
There are two ways to change the size and position of the squiggle.
One way is to change all the number that are passed to the CGContextAddCurveToPoint
function. For example, if you adjust the x
values with x = (x-3) * 0.9524
and adjust all the y
values with y = (y-8) * 0.9524
, then the squiggle fits nicely into a 100x50 rectangle.
The other way is to change the affine transform of your drawing context before drawing the squiggle. You can apply translation and scale transformations to place/size the squiggle wherever you want it. Note that the order in which the transformations are applied is important. Also, you can save and restore the graphics state so that the transformations are only applied to the squiggle, and not other items that you are drawing. The code above moves the squiggle 100 pixels down, and makes it twice as big.