Рисуйте изображения равномерно по пути в iOS - PullRequest
5 голосов
/ 05 августа 2011

Что я хочу сделать, так это провести пальцем по экрану (touchesMoved) и нарисовать равномерно расположенные изображения (возможно, CGImageRefs) вдоль точек, созданных touchesMoved.Я могу рисовать линии, но то, что я хочу создать, выглядит примерно так (для этого примера я использую изображение стрелки, но это может быть любое изображение, это может быть изображение моей собаки :)) Главное,чтобы обеспечить равномерное распределение изображений при рисовании пальцем на iPhone или iPad.

enter image description here

Ответы [ 2 ]

8 голосов
/ 06 августа 2011

Прежде всего ОГРОМНЫЕ реквизиты выходят в Кендалл.Итак, основываясь на его ответе, вот код для взятия UIImage, рисования его на экране вдоль пути (не реального pathRef, просто логический путь, созданный точками) на основе расстояния между касаниями, а затем поворот изображенияправильно на основе вектора текущей и предыдущей точек.Надеюсь, вам понравится:

Сначала вам нужно загрузить изображение, которое будет использоваться в качестве CGImage снова и снова:

NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"arrow.png" ofType:nil];
  UIImage *img = [UIImage imageWithContentsOfFile:imagePath];
  image = CGImageRetain(img.CGImage);

убедитесь, что в вашем контенте вы звоните

 CGImageRelease(image);

затем в touchesBegan, просто сохраните начальную точку в переменной, которая выходит за пределы метода (объявите ее в своем заголовке следующим образом :), в этом случае я рисую в UIView

@interface myView : UIView {
    CGPoint lastPoint;
    }
@end

затем в касаниях Началось:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

UITouch *touch = [touches anyObject];
lastPoint = [touch locationInView:self];

}

и, наконец, в touchsMoved, нарисуйте растровое изображение на экране, а затем, когда ваше расстояниедостаточно переместил (в моем случае 73, так как мое изображение 73 пикселя x 73 пикселя), выведите это изображение на экран, сохраните новое изображение и установите lastPoint равным currentPoint

     -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    {

        UITouch *touch = [touches anyObject];   
        currentPoint = [touch locationInView:self];

        double deltaX = lastPoint.x - currentPoint.x;
        double deltaY = lastPoint.y - currentPoint.y;

        double powX = pow(deltaX,2);
        double powY = pow(deltaY,2);

        double distance = sqrt(powX + powY);
        if (distance >= 73){

            lastPoint = currentPoint;

             UIGraphicsBeginImageContext(self.frame.size);
            [drawImage.image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
            CGContextSaveGState(UIGraphicsGetCurrentContext());

            float angle = atan2(deltaX, deltaY);
            angle *= (M_PI / 180);


            CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(currentPoint.x, currentPoint.y, 73, 73),[self CGImageRotatedByAngle:image angle:angle * -1]);
            CGContextRestoreGState(UIGraphicsGetCurrentContext());
             drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
            distance = 0;

        }

    }


    - (CGImageRef)CGImageRotatedByAngle:(CGImageRef)imgRef angle:(CGFloat)angle
{
    CGFloat angleInRadians = angle * (M_PI / 180);
    CGFloat width = CGImageGetWidth(imgRef);
    CGFloat height = CGImageGetHeight(imgRef);

    CGRect imgRect = CGRectMake(0, 0, width, height);
    CGAffineTransform transform = CGAffineTransformMakeRotation(angleInRadians);
    CGRect rotatedRect = CGRectApplyAffineTransform(imgRect, transform);

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef bmContext = CGBitmapContextCreate(NULL,
                                                   rotatedRect.size.width,
                                                   rotatedRect.size.height,
                                                   8,
                                                   0,
                                                   colorSpace,
                                                   kCGImageAlphaPremultipliedFirst);
    CGContextSetAllowsAntialiasing(bmContext, FALSE);
    CGContextSetInterpolationQuality(bmContext, kCGInterpolationNone);
    CGColorSpaceRelease(colorSpace);
    CGContextTranslateCTM(bmContext,
                          +(rotatedRect.size.width/2),
                          +(rotatedRect.size.height/2));
    CGContextRotateCTM(bmContext, angleInRadians);
    CGContextTranslateCTM(bmContext,
                          -(rotatedRect.size.width/2),
                          -(rotatedRect.size.height/2));
    CGContextDrawImage(bmContext, CGRectMake(0, 0,
                                             rotatedRect.size.width,
                                             rotatedRect.size.height),
                       imgRef);

    CGImageRef rotatedImage = CGBitmapContextCreateImage(bmContext);
    CFRelease(bmContext);
    [(id)rotatedImage autorelease];

    return rotatedImage;
}

, это создаст изображение, котороевыглядит следующим образом:

enter image description here

Собираюсь добавить следующее (с некоторыми изменениями в приведенном выше коде, чтобы попытаться заполнить пустоты, где touchchesMoved пропускает некоторые точки при перемещениибыстро:

CGPoint point1 = CGPointMake(100, 200);

CGPoint point2 = CGPointMake(300, 100);



double deltaX = point2.x - point1.x;
double deltaY = point2.y - point1.y;

double powX = pow(deltaX,2);
double powY = pow(deltaY,2);

double distance = sqrt(powX + powY);

distance = 0;


for (int j = 1; j * 73 < distance; j++ )
{
    double x =  (point1.x + ((deltaX / distance) * 73 * j));
    double y =  (point1.y + ((deltaY / distance) * 73 * j));


    NSLog(@"My new point is x: %f y :%f", x, y);
}
2 голосов
/ 05 августа 2011

Предполагая, что у вас уже есть код, который отслеживает касание пользователя при перемещении его касания по экрану, звучит так, будто вы хотите определить, когда они переместились на расстояние, равное длине вашего изображения, и в это время вы хотите нарисуйте еще одну копию вашего изображения под их прикосновением.

Чтобы достичь этого, я думаю, вам нужно:

  • Рассчитайте длину (ширину) вашего изображения
  • реализовать код для рисования копий вашего изображения на экране, повернутый на любой угол
  • каждый раз, когда сенсор перемещается пользователем (например, в touchsMoved :):
    • вычисляет дельту касания при каждом его перемещении и генерирует "длину" этой дельты (например, что-то вроде sqrt (dx ^ 2 + dy ^ 2)) *
    • накапливает расстояние с момента рисования последнего изображения
    • если расстояние достигло длины вашего изображения, нарисуйте копию вашего изображения под текущим положением касания, повернутым соответствующим образом (возможно, в соответствии с вектором от положения последнего изображения до текущего положения)

Как это звучит?

...