2013-03-22 10 views
10

Я рисую линию, используя следующий код, он работает просто изумительно,Line Drawing + Пересечение этой линии с себя, а также обнаружить CCSprites внутри этой нарисованной линии

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

Теперь я хочу, чтобы ... ..

1> Обнаружение, если линия пересекает с собой. 2) Обнаружение, если CCSprite находится внутри этой закрытой линии или нет.

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

  1. Первый метод

    - (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; 
    } 
    

И это, как я называю этот метод, я хранить свои очки в arrLinePoints от метода pangesture распознавателя

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

Это дает я правдивый даже со следующей ситуацией

enter image description here

Я также попробовал ту же функциональность с другим подходом, добавив вид в поле зрения CCDirector в

UIBezierPath intersect

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

Идеальная ситуация для пересечения является

enter image description here

Пожалуйста, помогите как можно скорее! Спасибо за поддержку.

+0

Я хочу обнаружить пересечение одной линии в Cocos2d. – Anand

+0

Не реализовано, хотя, я думаю, вы можете обнаружить значение пикселя линии, нарисованной с помощью значения пикселя вашей нарисованной линии внутри метода 'touchhesMoved'. – NiKKi

+0

Посмотрите на scribus/lib2geom functionfind_self_intersections http://www.scribus.net/svn/Scribus/branches/ScribusOTF/scribus/plugins/tools/2geomtools/lib2geom/basic-intersection.cpp. Это может быть поучительно –

ответ

1

Не реализовано, хотя, я думаю, вы можете обнаружить значение пикселя линии, нарисованной с помощью значения пикселя вашей нарисованной линии внутри метода touchhesMoved. Или вы можете обратиться к here за подробным подходом. Эта же работа была проделана здесь.

3

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

Неплохо, чтобы найти хороший алгоритм пересечения сегментов линии. Похоже, верховный ответ на этот вопрос имеет хороший метод: Determining if two line segments intersect?

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

Оттуда вы должны быть способны выполнить тест «точка в полигоне».

Несколько советов по производительности:

  1. В поисках пересечения, только проверить новейший линейный сегмент для столкновения с другими (все линии, которые не пересекаются, ранее не пересекаются друг с другом в этот раз)
  2. вы можете пропустить сегменты, когда можно сделать вывод, что обе точки находятся на одном полюсе отрезка, например, вы можете пропустить, если иностранный: current.ax < current.bx & & (foreign.ax < current.ax & & foreign.b.x < current.a.x)

Надеюсь, это поможет вам.

+0

Спасибо за хорошее предложение. – Anand

+0

+1 для предложения сегмента линии и второго предложения производительности (1-й, однако, я думаю, это мусор). –

+0

Я отредактировал 1-е предложение, пояснив это, надеюсь, сделать его менее мусором. – cantgetright82