2013-12-13 2 views
0

Я использую UILongPressGestureRecognizer, который отлично работает, но данные, которые я получаю, недостаточно точны для моего использования. Я думаю, что CGPoints, которые я получаю, округлены.Более точный CGPoint для UILongPressGestureRecognizer

Пример точек, которые я получаю: 100,5, 103,0 и т. Д. Десятичная часть равна либо .5, либо .0. Есть ли способ получить более точные точки? Я надеялся на что-то вроде .xxxx, как в «100.8745», но .xx сделал бы это.

Редактировать: Причина, по которой мне это нужно, потому что у меня есть круговой UIBezierPath, я хочу ограничить жест перетаскивания только этим круговым путем. Элемент должен перемещаться только по окружности этого круга. Для этого я вычислил 720 точек на границе круга, используя его радиус. Теперь эти точки - .xxxx. Если я их закругляю, сопротивление не так гладко вокруг средней части круга. Это потому, что в средней части экватора точки на координате x очень близки друг к другу. Поэтому, когда я закруглялся по координате y, я потерял много очков и, следовательно, «не очень гладкое» действие по перетаскиванию.

Вот как я вычислить точки

for (CGFloat i = -154;i<154;i++) { 

    CGPoint point = [self pointAroundCircumferenceFromCenter:center forX:i]; 
    [bezierPoints addObject:[NSValue valueWithCGPoint:point]]; 
    i = i - .5; 
} 

- (CGPoint)pointAroundCircumferenceFromCenter:(CGPoint)center forX:(CGFloat)x 
{ 
CGFloat radius = 154; 
CGPoint upperPoint = CGPointZero; 
CGPoint lowerPoint = CGPointZero; 

//theta used to be the x variable. was first calculating points using the angle 
/* point.x = center.x + radius * cosf(theta); 
point.y = center.y + radius * sinf(theta);*/ 

CGFloat y = (radius*radius) - (theta*theta); 
upperPoint.x = x+156; 
upperPoint.y = 230-sqrtf(y); 
lowerPoint.x = x+156; 
lowerPoint.y = sqrtf(y)+230; 

NSLog(@"x = %f, y = %f",upperPoint.x, upperPoint.y); 
[lowerPoints addObject:[NSValue valueWithCGPoint:lowerPoint]]; 
[upperPoints addObject:[NSValue valueWithCGPoint:upperPoint]]; 
return upperPoint; 
} 

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

Вот как ограничить движение

-(void)handleLongPress:(UILongPressGestureRecognizer *)recognizer{ 
    CGPoint finalpoint; 
    CGPoint initialpoint; 
    CGFloat y; 
    CGFloat x; 
    CGPoint tempPoint; 
    if(recognizer.state == UIGestureRecognizerStateBegan){ 
     initialpoint = [recognizer locationInView:self.view]; 
     CGRect rect = CGRectMake(initialpoint.x, initialpoint.y, 40, 40); 
     self.hourHand.frame = rect; 
     self.hourHand.center = initialpoint; 
     NSLog(@"Long Press Activated at %f,%f",initialpoint.x, initialpoint.y); 
    } 
    else if (recognizer.state == UIGestureRecognizerStateChanged){ 
     CGPoint currentPoint = [recognizer locationInView:self.view]; 
     x = currentPoint.x-initialpoint.x; 
     y = currentPoint.y-initialpoint.y; 
     tempPoint = CGPointMake(currentPoint.x, currentPoint.y); 
     NSLog(@"temp point ::%f, %f", tempPoint.x, tempPoint.y); 
     tempPoint = [self givePointOnCircleForPoint:tempPoint]; 
     self.hourHand.center = tempPoint; 
    } 
    else if (recognizer.state == UIGestureRecognizerStateEnded){ 
    // finalpoint = [recognizer locationInView:self.view]; 
     CGRect rect = CGRectMake(tempPoint.x, tempPoint.y, 20, 20); 
     self.hourHand.frame = rect; 
     self.hourHand.center = tempPoint; 
     NSLog(@"Long Press DeActivated at %f,%f",tempPoint.x, tempPoint.y); 
    } 
} 

-(CGPoint)givePointOnCircleForPoint:(CGPoint) point{ 
CGPoint resultingPoint; 
for (NSValue *pointValue in allPoints){ 
    CGPoint pointFromArray = [pointValue CGPointValue]; 
    if (point.x == pointFromArray.x) { 
     // if(point.y > 230.0){ 
      resultingPoint = pointFromArray; 
      break; 
     // } 
    } 
} 

В принципе, я с й-координатой «прикоснулась точка» и возвращение у, сравнивая его с массивом точек я вычисленные ранее.

В настоящее время этот код работает для половины круга только потому, что каждый x имеет 2 y значения, потому что это круг. Игнорируйте это, потому что я думаю, что с этим можно легко справиться.

В картине, белый круг оригинальный круг, черный круг круг точек у меня есть из кода + форматирования, чтобы удалить точность, чтобы соответствовать вход я получаю. Если вы посмотрите вокруг экватора (красная выделенная часть), вы увидите разрыв между следующими точками. Этот пробел - моя проблема.

+1

Что вам нужно, что точность для? Будет ли палец на экране даже быть настолько точным? –

+1

Насколько я знаю, один пиксель составляет 0,5 балла на экране сетчатки. Таким образом, вы никогда не получите более высокое разрешение. –

+0

@ DavidRönnqvist добавил причину. Я думаю, что .xxxx слишком много, но .x звук разумный – nupac

ответ

2

Чтобы ответить на ваш первоначальный вопрос: на устройстве с дисплеем Retina один пиксель равен 0,5 баллам, поэтому 0.5 - лучшее разрешение, которое вы можете получить на этом оборудовании. (На устройствах без сетчатки, 1 пиксель = 1 балл.)

Но мне кажется, что вам не нужен этот массив точек. Если понять проблему правильно, вы можете использовать следующий код для «ограничить» (или «проект») произвольная точка на окружности:

CGPoint center = ...; // Center of the circle 
CGFloat radius = ...; // Radius of the circle 
CGPoint point = ...; // The touched point 
CGPoint resultingPoint; // Resulting point on the circumference 

// Distance from center to point: 
CGFloat dist = hypot(point.x - center.x, point.y - center.y); 
if (dist == 0) { 
    // The touched point is the circle center. 
    // Choose any point on the circumference: 
    resultingPoint = CGPointMake(center.x + radius, center.y); 
} else { 
    // Project point to circle circumference: 
    resultingPoint = CGPointMake(center.x + (point.x - center.x)*radius/dist, 
        center.y + (point.y - center.y)*radius/dist); 
} 
+0

Добавлена ​​фотография, чтобы лучше объяснить проблему. Разве ваш путь не замедлит его? – nupac

+0

@nupac: Почему это должно быть медленным? Это простой расчет вместо сравнения точки с массивом из 720 других точек. И это позволяет избежать всех проблем округления/точности или проблем из-за «ограниченного» разрешения 0,5 балла. –

+0

@nupac: Я обновил ответ с помощью нового кода, который позволяет избежать тригонометрических функций и может немного улучшиться. –

Смежные вопросы