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

Я рисую строку, используя следующий код, она работает просто потрясающе,

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

Теперь я хочу.....

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

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

  • Первый метод

    - (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 пересекается

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

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

enter image description here

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

Ответ 1

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

Не следует слишком сложно найти хороший алгоритм пересечения сегментов линии. Кажется, что лучший ответ на этот вопрос имеет хороший метод: Определение пересечения двух сегментов линии?

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

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

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

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

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

Ответ 2

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