Нарисуйте изображения, равномерно расположенные вдоль пути в iOS

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

введите здесь описание изображения


person cdasher    schedule 05.08.2011    source источник


Ответы (2)


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

Для этого, я думаю, вам потребуется:

  • рассчитать длину (ширину) вашего изображения
  • внедрить код для рисования копий вашего изображения на ваш вид, повернутых под любым углом
  • each time the user's touch moves (e.g. in touchesMoved:):
    • calculate the delta of the touch each time it moves and generate the "length" of that delta (e.g. something like sqrt(dx^2 + dy^2))
    • накапливать расстояние с момента отрисовки последнего изображения
    • если расстояние достигло длины вашего изображения, нарисуйте копию вашего изображения под текущим положением касания, повернув его соответствующим образом (возможно, в соответствии с вектором от положения последнего изображения до текущей позиции)

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

person Kendall Lister    schedule 05.08.2011
comment
Позвольте мне попробовать. Мне никогда не приходило в голову основывать размещение изображений на расстоянии. Я думал, что мне нужно будет добавить или скорректировать точки на пути. - person cdasher; 06.08.2011
comment
Именно то, что я искал, опубликую рабочий код, когда я его очистил. (Вы не в курсе, как рассчитать правильный вектор, не так ли :)) - person cdasher; 06.08.2011
comment
Хорошая работа по реализации этого и публикации вашего кода. Похоже, вам нужно немного сместить рисунок, чтобы кончики стрелок указывали на основание следующего. Попробуйте вычислить другой вектор, на этот раз повернутый на 90 градусов относительно ориентации изображения и длиной, равной половине ширины вашего изображения, затем добавьте этот вектор к вашим currentPoint.x и .y и посмотрите, как он выглядит. - person Kendall Lister; 06.08.2011
comment
Я в значительной степени Forest Gumped мой путь через векторную вещь. Так является ли ориентация изображений текущим углом? Или я создаю произвольную точку, которая находится на расстоянии половины ширины моего изображения, но на 90 градусов справа от ... ну, вы видите, что мое понимание векторов всего 45 минут :) - person cdasher; 06.08.2011
comment
Да! Под вектором я подразумевал положение (x, y), как вы уже поняли, поэтому теперь все, что вам нужно сделать, это найти правильное смещение, чтобы ваша серия стрелок выглядела гладкой. Я не проверял это, но мне кажется, что смещение каждой стрелки влево или вправо на половину ее ширины должно хорошо их выровнять, откуда и происходит поворот на 90 градусов: сдвиг влево/вправо должен быть относительно стрелки ориентация. - person Kendall Lister; 06.08.2011
comment
Хорошо, позвольте мне немного поразмыслить над этим. Я обновлю, когда разберусь. Спасибо! - person cdasher; 06.08.2011

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

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

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

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

 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];

}

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

     -(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;
}

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

введите здесь описание изображения

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

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);
}
person cdasher    schedule 06.08.2011
comment
Собираюсь добавить следующее (с некоторыми изменениями в приведенном выше коде, чтобы попытаться заполнить пустоты, где touchesMoved пропускает некоторые точки при быстром перемещении: - person cdasher; 11.08.2011
comment
Спасибо за вашу помощь, как я могу построить точки x и y, пожалуйста, предложите мне - person dineshprasanna; 05.09.2012
comment
Почему вы устанавливаете расстояние = 0 в самом нижнем поле кода перед циклом for? Как самый нижний блок кода помогает с быстрым движением? - person retrovius; 24.06.2017