2013-03-22 21 views
10

jestem rysowanie linii za pomocą następującego kodu, to działa po prostu niesamowite,rysowanie linii + przecięcia tej linii z siebie, a także wykryć CCSprites wewnątrz tej narysowanej linii

http://www.merowing.info/2012/04/drawing-smooth-lines-with-cocos2d-ios-inspired-by-paper/

Teraz chcę ... ..

1> Wykryj, czy linia przecina się z samym sobą. 2) Wykryj, czy CCSprite znajduje się w zamkniętej linii, czy nie.

Podczas wyszukiwania natknąłem się na wiele logik dla LineIntersection, ale żadna z nich nie jest dokładna. Daję jedną z nich, która wykrywa skrzyżowanie, ale także wykrywa ją, gdy nie ma przecięcia linii.

  1. Pierwsza metoda

    - (BOOL) lineIntersectOccured:(CGPoint)t1 pointEnd:(CGPoint)t2 
    { 
        BOOL result = NO; 
        int pointsCount = [arrlinePoints count]; 
    
        CGPoint cp1; 
        CGPoint cp2; 
    
        for(int i = 0, j = 1; j < pointsCount; i++,j++) 
        { 
         [[arrlinePoints objectAtIndex:i] getValue:&cp1]; 
         [[arrlinePoints objectAtIndex:j] getValue:&cp2]; 
    
         // lines connected do not need to be included. 
         if((cp2.x == t1.x && cp2.y == t1.y) || (cp1.x == t2.x && cp1.y == t2.y)) 
         { 
          continue; 
         } 
    
         CGPoint diffLA = CGPointMake(cp2.x - cp1.x,cp2.y - cp1.y); 
         CGPoint diffLB = CGPointMake(t2.x - t1.x, t2.y - t1.y); 
    
         float compA = diffLA.x*cp1.y - diffLA.y * cp1.x; 
         float compB = diffLB.x*t1.y - diffLB.y*t1.x; 
    
         BOOL compA1 = (diffLA.x*t1.y - diffLA.y*t1.x) < compA; 
         BOOL compA2 = (diffLA.x*t2.y - diffLA.y*t2.x) < compA; 
         BOOL compB1 = (diffLB.x*cp1.y - diffLB.y*cp1.x) < compB; 
         BOOL compB2 = (diffLB.x*cp2.y - diffLB.y*cp2.x) < compB; 
    
         if(((!compA1 && compA2) || (compA1 && !compA2)) && ((!compB1 && compB2) || (compB1 && !compB2))) 
         { 
          result = YES; 
         } 
        } 
        return result; 
    } 
    

I to jest, jak się nazywają tę metodę, Mam przechowywane moje punkty w arrLinePoints od sposobu pangesture Rozpoznawania

if ([self lineIntersectOccured:[[arrlinePoints objectAtIndex:0] CGPointValue] pointEnd:[[arrlinePoints objectAtIndex:[arrlinePoints count] - 1] CGPointValue]]) 
    { 
     NSLog(@"Line Intersected"); 
    } 

Daje to dla mnie, nawet przy następującej sytuacji:

enter image description here

ja też próbowałem tę samą funkcjonalność z innego podejścia poprzez dodanie widoku w widoku CCDirector za

UIBezierPath intersect

Ale to daje problemy z wydajnością, moje fps zredukowane do prawie 3 do 6. A również ten problem z skrzyżowaniem pozostaje ten sam.

Perfect Sytuacja na skrzyżowaniu

enter image description here

Proszę o pomoc jak najszybciej! Dzięki za wsparcie.

+0

Chcę wykryć przecięcie tej samej linii w Cocos2d. – Anand

+0

Nie zaimplementowane, domyślam się, że możesz wykryć wartość pikseli linii narysowanej za pomocą wartości pikseli narysowanej linii wewnątrz metody 'touchesMoved'. – NiKKi

+0

Spójrz na scribus/lib2geom functionfind_self_intersections http://www.scribus.net/svn/Scribus/branches/ScribusOTF/scribus/plugins/tools/2geomtools/lib2geom/basic-intersection.cpp. Może to być pouczające –

Odpowiedz

1

Nie zaimplementowano, myślę, że możesz wykryć wartość pikseli linii narysowanej za pomocą wartości pikseli narysowanej linii wewnątrz metody touchesMoved. Lub możesz skierować here dla szczegółowego podejścia. Ta sama praca została wykonana tutaj.

3

Podczas konstruowania ścieżki samodzielnie, nie powinno być konieczne testowanie pikseli. Zamiast tego użyj punktów użytych do utworzenia ścieżki.

Nie powinno być zbyt trudno znaleźć dobry algorytm przecięcia segmentów linii. Wydaje się, że najlepszą odpowiedzią na to pytanie jest dobra metoda: Determining if two line segments intersect?

Po znalezieniu trafienia, użyj tego dokładnego punktu trafienia i historii punktów, aby utworzyć wielokąt.

Stamtąd powinno być możliwe wykonanie testu "punkt w wielokącie".

Kilka porad dla usług:

  1. W poszukiwaniu skrzyżowania, tylko sprawdzić najnowszy odcinek do kolizji z innymi (wszystkie linie, które nie przecinają się wcześniej nie przecinają się ze sobą tym razem)
  2. Możecie pominąć segmenty, gdy można stwierdzić, że oba punkty są na jednym krańcu odcinka linii, na przykład można pominąć, jeśli zagraniczny: current.ax < current.bx & & (foreign.ax < current.ax & & foreign.b.x < current.a.x)

Mam nadzieję, że to wam pomoże.

+0

Dzięki za miła sugestia. – Anand

+0

+1 dla sugestii segmentu linii i drugiej sugestii działania (pierwsza myślę, że to bzdura). –

+0

Edytowałem pierwszą sugestię, aby to wyjaśnić, miejmy nadzieję, że sprawi, że będzie mniej śmieci. – cantgetright82

Powiązane problemy