Jak znaleźć odległość między dwoma punktami CG?

84

Kiedy wykonujemy multitouch dwoma palcami w UIScrollView, otrzymujemy dwa punkty CG. Chcę znaleźć odległość między nimi. Następnie, gdy ponownie zrobimy szczypanie (wewnątrz lub na zewnątrz), wtedy znowu otrzymamy dwa punkty. Następnie po ponownym znalezieniu odległości między tymi dwoma punktami chcę zdecydować, czy uszczypnąłem, czy wyciągnąłem. Jeśli uszczypnąłem, na pewno nowa odległość będzie mniejsza i odwrotnie.

Ale nie wiesz, jak znaleźć dokładny pomiar odległości między 2 punktami w celu porównania? Czy ktoś ma o tym pojęcie?

rosomak
źródło
Zobacz moją odpowiedź dla Swift 4, która pokazuje do 5 różnych sposobów na znalezienie odległości między dwoma CGPoints.
Imanou Petit

Odpowiedzi:

125

Odległość między p1a p2:

CGFloat xDist = (p2.x - p1.x);
CGFloat yDist = (p2.y - p1.y);
CGFloat distance = sqrt(xDist * xDist + yDist * yDist);

Wstaw funkcję:

func distance(_ a: CGPoint, _ b: CGPoint) -> CGFloat {
    let xDist = a.x - b.x
    let yDist = a.y - b.y
    return CGFloat(sqrt(xDist * xDist + yDist * yDist))
}

Wstęp: twierdzenie Pitagorasa

Jeśli chcesz tylko obliczyć, czy odległość między punktami rośnie, czy maleje, możesz pominąć funkcję sqrt (), która przyspieszy ją trochę.

Ole Begemann
źródło
32
Czy nie ma na to wygodnej metody?
SpacyRicochet
22
Aksjomat # 1 geometrii obliczeniowej: jeśli porównujesz odległości, nie ma potrzeby ponoszenia kosztu operacji sqrt ().
QED
4
@SpaceyRicochet istnieją metody hypotf i ccpDistance. Zobacz odpowiedzi poniżej.
rmp251
@QED Czy wartość przed obliczeniem pierwiastka kwadratowego ma nazwę lub znaczenie wykraczające poza pośredni krok obliczania odległości?
allenh
@AllenHumphreys nie ma nic bardziej poetyckiego niż kwadrat do kwadratu .
QED,
188

Możesz użyć funkcji hypot()lub hypotf()do obliczenia przeciwprostokątnej. Biorąc pod uwagę dwa punkty p1i p2:

CGFloat distance = hypotf(p1.x - p2.x, p1.y - p2.y);

I to wszystko.

Lucjusz
źródło
4
jeśli używasz swift to odległość = hypotf (Float (p1.x) - Float (p2.x), Float (p1.y) - Float (p2.y))
nwales
6
masz na myślilet distance = hypotf(Float(p1.x - p2.x), Float(p1.y - p2.y))
przeciętny Joe
6
masz na myśli let distance = hypot(p1.x - p2.x, p1.y - p2.y)od Swift 2.1
Cemen
Ta funkcja jest właściwie powodem, dla którego szukałem tego pytania.
kelin
30

Dla szybkich użytkowników

extension CGPoint {
    func distance(to point: CGPoint) -> CGFloat {
        return sqrt(pow(x - point.x, 2) + pow(y - point.y, 2))
    }
}
Daniel Krom
źródło
To naprawdę fajne rozwiązanie! Działa w porządku!
gundrabur
15

W Swift 4 możesz wybrać jeden z 5 następujących kodów Playground, aby uzyskać odległość między dwoma CGPointinstancjami.


1. Korzystanie z sqrt(_:)funkcji Darwina

import CoreGraphics

func distance(from lhs: CGPoint, to rhs: CGPoint) -> CGFloat {
    let xDistance = lhs.x - rhs.x
    let yDistance = lhs.y - rhs.y
    return sqrt(xDistance * xDistance + yDistance * yDistance)
}

let point1 = CGPoint(x: -10, y: -100)
let point2 = CGPoint(x: 30, y: 600)

distance(from: point1, to: point2) // 701.141925718324

2. Za pomocą CGFloat squareRoot()metody

import CoreGraphics

func distance(from lhs: CGPoint, to rhs: CGPoint) -> CGFloat {
    let xDistance = lhs.x - rhs.x
    let yDistance = lhs.y - rhs.y
    return (xDistance * xDistance + yDistance * yDistance).squareRoot()
}

let point1 = CGPoint(x: -10, y: -100)
let point2 = CGPoint(x: 30, y: 600)

distance(from: point1, to: point2) // 701.141925718324

3. Stosowanie CGFloat squareRoot()metody i pow(_:_:)funkcji Core Graphics

import CoreGraphics

func distance(from lhs: CGPoint, to rhs: CGPoint) -> CGFloat {
    return (pow(lhs.x - rhs.x, 2) + pow(lhs.y - rhs.y, 2)).squareRoot()
}

let point1 = CGPoint(x: -10, y: -100)
let point2 = CGPoint(x: 30, y: 600)

distance(from: point1, to: point2) // 701.141925718324

4. Korzystanie z hypot(_:_:)funkcji Core Graphics

import CoreGraphics

func distance(from lhs: CGPoint, to rhs: CGPoint) -> CGFloat {
    return hypot(lhs.x - rhs.x, lhs.y - rhs.y)
}

let point1 = CGPoint(x: -10, y: -100)
let point2 = CGPoint(x: 30, y: 600)

distance(from: point1, to: point2) // 701.141925718324

5. Wykorzystanie hypot(_:_:)funkcji i CGFloat distance(to:)metody Core Graphics

import CoreGraphics

func distance(from lhs: CGPoint, to rhs: CGPoint) -> CGFloat {
    return hypot(lhs.x.distance(to: rhs.x), lhs.y.distance(to: rhs.y))
}

let point1 = CGPoint(x: -10, y: -100)
let point2 = CGPoint(x: 30, y: 600)

distance(from: point1, to: point2) // 701.141925718324
Imanou Petit
źródło
1
Działa również w Swift 3.
ThisClark,
12
-(float)distanceFrom:(CGPoint)point1 to:(CGPoint)point2
{
CGFloat xDist = (point2.x - point1.x);
CGFloat yDist = (point2.y - point1.y);
return sqrt((xDist * xDist) + (yDist * yDist));
}

Jeśli używasz cocos2d

float distance = ccpDistance(point1, point2);
haawa
źródło
2
Wygląda na to, że ccpDistance jest częścią cocos2d, a nie częścią core. Włączenie go w celu uniknięcia twierdzenia Pitagorasa jest prawdopodobnie przesadą.
Vox,
3

Napisałem to, często go używam:

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

Zadzwoń tak:

float distanceMoved = [self distanceBetween touchStart and: touchEnd];

Zwykle używam cocos2d, ale nadal używam własnej funkcji do niektórych rzeczy, ponieważ kiedy się uczyłem, napisałem kilka własnych funkcji dla prostych rzeczy, zamiast szukać "oficjalnych" funkcji wyższego rzędu, a ponadto nie jestem wielki fan funkcji (vars, vars), wolę [self functions vars and: vars]

redux
źródło
1
czy nie powinno to być sqrt (pow (p2.x-p1.x, 2) + pow (p2.y-p1.y, 2))? drugie wystąpienie p2.y zastąpiło p1.y.
Sanjay Chaudhry,
0
#define rw_pointOffset(point1, point2) CGPointMake(point2.x - point1.x, point2.y - point1.y)
#define rw_pointDistance(point1, point2) sqrtf( powf(point2.x - point1.x, 2.0f) + powf(point2.y - point1.y, 2.0f))

I tak z tego korzystasz:

CGPoint offset = rw_pointOffset(view1.center, view2.center);
float distance = rw_pointDistance(view1.center, view2.center);
kokosowiec
źródło
0

Jeśli chcesz znaleźć bezwzględną wartość odległości między dwoma punktami, możesz użyć (dla Cocos2d):

float distance = abs(ccpDistance(point1, point2));
user2425159
źródło