Рисование линии + пересечение этой линии с самим собой, а также обнаружение 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");
  }

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

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

UIBezierPath пересекаются

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

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

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

2 ответа

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

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

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

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

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

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

Я надеюсь, что это поможет вам.

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

Другие вопросы по тегам