2014-01-21 4 views
11

У меня есть два скнода на экране. Каков наилучший способ рассчитать расстояние («как вороньи» тип расстояния, мне не нужен вектор и т. Д.)?ios - Spritekit - Как рассчитать расстояние между двумя узлами?

Я имел Google и поиск здесь и не могу найти что-то, что покрывает это (там не слишком много нитей на StackOverflow о наборе спрайтов)

ответ

20

Вот функция, которая сделает это за вас. Это из примера Приключения закодировать Apple:

CGFloat SDistanceBetweenPoints(CGPoint first, CGPoint second) { 
    return hypotf(second.x - first.x, second.y - first.y); 
} 

Чтобы вызвать эту функцию из кода:

CGFloat distance = SDistanceBetweenPoints(nodeA.position, nodeB.position); 
0

теорема Пифагора:

- (float)getDistanceBetween:(CGPoint)p1 and:(CGPoint)p2 { 
    return sqrt(pow(p2.x-p1.x,2)+pow(p2.y-p1.y,2)); 
} 
5

joshd и Андрей Гордеев оба правильны, с решением Гордеева изложив, что функция делает hypotf.

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

- (float)getDistanceSquared:(CGPoint)p1 and:(CGPoint)p2 { 
    return pow(p2.x - p1.x, 2) + pow(p2.y - p1.y, 2); 
} 

Для того, чтобы использовать эту функцию для вычисления, если какие-либо спрайтов находятся в пределах радиуса от центра вида в обновлении: метод подкласса SKScene:

-(void)update:(CFTimeInterval)currentTime { 
    CGFloat radiusSquared = pow (self.closeDistance, 2); 
    CGPoint center = self.view.center; 
    for (SKNode *node in self.children) { 
     if (radiusSquared > [self getDistanceSquared:center and:node.position]) { 
      // This node is close to the center. 
     }; 
    } 
} 
+0

Использование '(p2.x-p1.y) * (p2.x-p1.y)' может быть большим улучшением производительности над 'pow', потому что' pow' предназначен для двух пар. – Tim

+0

, вы можете использовать 'powf', который принимает два поплавка. – Austin

+0

Это отличный трюк, который мне никогда не приходило в голову! Благодарю. – colinta

2

Свифта:

extension CGPoint { 

    /** 
    Calculates a distance to the given point. 

    :param: point - the point to calculate a distance to 

    :returns: distance between current and the given points 
    */ 
    func distance(point: CGPoint) -> CGFloat { 
     let dx = self.x - point.x 
     let dy = self.y - point.y 
     return sqrt(dx * dx + dy * dy); 
    } 
} 
+0

Как бы вы это использовали? Я понимаю суть: передал последнюю часть каждого из dx и dy, но что такое «я», и как это получается? – Confused

+0

@confused Поскольку это расширение, я бы понял, что это добавляет возможность вызова .distance() в экземпляре CGPoint, поэтому вы должны использовать его следующим образом: 'var theDistance = point1.distance (point2)' – Brad

5

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

extension CGPoint { 
    func distance(point: CGPoint) -> CGFloat { 
     return abs(CGFloat(hypotf(Float(point.x - x), Float(point.y - y)))) 
    } 
} 

Не скоро ли грандиозный?

+0

Это помогли мне так много! Спасибо – TheValyreanGroup

+1

is abs() необходимо? Разве hypot() всегда возвращает неотрицательное значение? –

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