Il seguente algoritmo può essere utilizzato per verificare se due (ruotato o altrimenti trasformati) visite sovrappongono:
- Usa
[view convertPoint:point toView:nil]
per convertire i 4 punti di confine dei due viste ad un sistema di coordinate comune (le coordinate finestra).
- I punti convertiti formano due quadrilateri convessi.
- Utilizzare SAT (Separating Axis Theorem) per verificare se i quadrilateri si intersecano.
Questo: http://www.geometrictools.com/Documentation/MethodOfSeparatingAxes.pdf è un'altra descrizione dell'algoritmo contenente pseudo-codice, più può essere trovato da googling "Separazione asse Teorema".
Update: Ho cercato di creare un metodo di Objective-C per la "Separazione Asse Teorema", e questo è quello che ho ottenuto. Fino ad ora, ho fatto solo alcuni test, quindi spero che non ci siano troppi errori.
- (BOOL)convexPolygon:(CGPoint *)poly1 count:(int)count1 intersectsWith:(CGPoint *)poly2 count:(int)count2;
test se 2 poligoni convessi si intersecano. Entrambi i poligoni vengono forniti come una serie CGPoint
dei vertici.
- (BOOL)view:(UIView *)view1 intersectsWith:(UIView *)view2
test (come descritto sopra) se due viste arbitrarie si intersecano.
Implementazione:
- (void)projectionOfPolygon:(CGPoint *)poly count:(int)count onto:(CGPoint)perp min:(CGFloat *)minp max:(CGFloat *)maxp
{
CGFloat minproj = MAXFLOAT;
CGFloat maxproj = -MAXFLOAT;
for (int j = 0; j < count; j++) {
CGFloat proj = poly[j].x * perp.x + poly[j].y * perp.y;
if (proj > maxproj)
maxproj = proj;
if (proj < minproj)
minproj = proj;
}
*minp = minproj;
*maxp = maxproj;
}
-(BOOL)convexPolygon:(CGPoint *)poly1 count:(int)count1 intersectsWith:(CGPoint *)poly2 count:(int)count2
{
for (int i = 0; i < count1; i++) {
// Perpendicular vector for one edge of poly1:
CGPoint p1 = poly1[i];
CGPoint p2 = poly1[(i+1) % count1];
CGPoint perp = CGPointMake(- (p2.y - p1.y), p2.x - p1.x);
// Projection intervals of poly1, poly2 onto perpendicular vector:
CGFloat minp1, maxp1, minp2, maxp2;
[self projectionOfPolygon:poly1 count:count1 onto:perp min:&minp1 max:&maxp1];
[self projectionOfPolygon:poly2 count:count1 onto:perp min:&minp2 max:&maxp2];
// If projections do not overlap then we have a "separating axis"
// which means that the polygons do not intersect:
if (maxp1 < minp2 || maxp2 < minp1)
return NO;
}
// And now the other way around with edges from poly2:
for (int i = 0; i < count2; i++) {
CGPoint p1 = poly2[i];
CGPoint p2 = poly2[(i+1) % count2];
CGPoint perp = CGPointMake(- (p2.y - p1.y), p2.x - p1.x);
CGFloat minp1, maxp1, minp2, maxp2;
[self projectionOfPolygon:poly1 count:count1 onto:perp min:&minp1 max:&maxp1];
[self projectionOfPolygon:poly2 count:count1 onto:perp min:&minp2 max:&maxp2];
if (maxp1 < minp2 || maxp2 < minp1)
return NO;
}
// No separating axis found, then the polygons must intersect:
return YES;
}
- (BOOL)view:(UIView *)view1 intersectsWith:(UIView *)view2
{
CGPoint poly1[4];
CGRect bounds1 = view1.bounds;
poly1[0] = [view1 convertPoint:bounds1.origin toView:nil];
poly1[1] = [view1 convertPoint:CGPointMake(bounds1.origin.x + bounds1.size.width, bounds1.origin.y) toView:nil];
poly1[2] = [view1 convertPoint:CGPointMake(bounds1.origin.x + bounds1.size.width, bounds1.origin.y + bounds1.size.height) toView:nil];
poly1[3] = [view1 convertPoint:CGPointMake(bounds1.origin.x, bounds1.origin.y + bounds1.size.height) toView:nil];
CGPoint poly2[4];
CGRect bounds2 = view2.bounds;
poly2[0] = [view2 convertPoint:bounds2.origin toView:nil];
poly2[1] = [view2 convertPoint:CGPointMake(bounds2.origin.x + bounds2.size.width, bounds2.origin.y) toView:nil];
poly2[2] = [view2 convertPoint:CGPointMake(bounds2.origin.x + bounds2.size.width, bounds2.origin.y + bounds2.size.height) toView:nil];
poly2[3] = [view2 convertPoint:CGPointMake(bounds2.origin.x, bounds2.origin.y + bounds2.size.height) toView:nil];
return [self convexPolygon:poly1 count:4 intersectsWith:poly2 count:4];
}
fonte
2013-03-29 21:02:09
Un'altra descrizione dell'algoritmo: http://stackoverflow.com/a/115520/1187415. –
Brillante! Grazie mille! – David
@MartinR Ho posto una nuova domanda [qui] (http://stackoverflow.com/questions/26821725/determine-if-crop-rect-is-entally-contained-within-rotated-uiview) basata su questa domanda/risposta. Ti chiedi se puoi dargli un'occhiata vedi? – brandonscript