如何使用objective-c在纸牌游戏中绘制完美的波浪线?

dum*_*uke 4 drawing objective-c cs193p

我正在尝试在 Set Card Game 中绘制曲线。输出甚至不接近我想要的。我应该如何改进绘图?

  • 请忽略“我想要的”图片中的阴影。我已经想出了如何做到这一点。问题是如何绘制曲线的形状
  • 这样做的目的是用objective-c练习绘图。所以在这里只使用 png 图片不是解决方案......

..

#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;
}
Run Code Online (Sandbox Code Playgroud)
  • 我得到了什么:

我得到了什么

  • 我想要的是:

我想要的是


最终版本

- (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;
}
Run Code Online (Sandbox Code Playgroud)

use*_*109 5

这是一些生成相当不错的波浪线再现的代码

- (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 );
}
Run Code Online (Sandbox Code Playgroud)

这就是它产生的

在此处输入图片说明


缩放和平移 Squiggle

有两种方法可以改变波浪线的大小和位置。

一种方法是更改​​传递给CGContextAddCurveToPoint函数的所有数字。例如,如果您使用 调整xx = (x-3) * 0.9524并使用 调整所有yy = (y-8) * 0.9524,则波浪线非常适合 100x50 矩形。

另一种方法是在绘制波浪线之前更改绘图上下文的仿射变换。您可以应用平移和缩放变换来将波浪线放置在任何您想要的位置/大小。请注意,应用转换的顺序很重要。此外,您可以保存和恢复图形状态,以便变换仅应用于波浪线,而不应用于您正在绘制的其他项目。上面的代码将波浪线向下移动 100 个像素,使其大一倍。