Подтвердить что ты не робот

Как я могу получить все точки в кривой CGPath или квадрантной кривой

Я сделал путь с четырьмя кривыми, используя метод CGPathAddQuadCurveToPoint. Я отлично прошел путь. Но я хочу знать все координатные точки, участвующие в пути.

Есть ли способ получить все координатные точки в пути?

Если у вас нет другого решения для математического извлечения всех точек кривой.

Спасибо заранее, Вамши

4b9b3361

Ответ 1

Вы можете сделать это, используя библиотечную программу wykobi С++ для кубических кривых безье. Библиотека Wykobi поддерживает также квадратичные кривые Безье.

Конечно, как заметил кто-то, вам не нужны все очки (хотя это и не невозможно, это просто займет бесконечное время:). Wykobi позволяет легко получить определенное количество очков - если ваш старт, c1, c2 и конечные точки (где c1, c2 - контрольные точки) точно такие же, как те, что указаны для CGContextAddCurveToPoint, тогда точки будут отлично расположены на линии, нарисованной основной графикой, - поэтому вы можете делать такие вещи, как рисовать рисунок в нескольких точках пути.

Смотрите: http://www.codeproject.com/Articles/22568/Computational-Geometry-C-and-Wykobi

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

Я создал С++-класс WPoint как мост между точками wykobi и CGPoints (С++ fun!). Здесь некоторый код (без WPoint, но вы можете себе представить, что это точно такой же макет, что и CGPoint, поэтому, если вы делаете правильный выбор, вы можете легко конвертировать.

        NSMutableArray* result = [[NSMutableArray alloc] init];
        wykobi::cubic_bezier<CGFloat,2> bezier;
        bezier[0] = (WPoint)p1;  // start point, in CG we did a CGMoveToPoint
        bezier[1] = (WPoint)b1i; // control 1
        bezier[2] = (WPoint)b2i; // control 2
        bezier[3] = (WPoint)p2;  // end point

        std::vector<WPoint> point_list;
        int numPoints = p2.dist(p3) * pointDensity;
        // *** here the magic ***
        wykobi::generate_bezier(bezier,std::back_inserter(point_list), numPoints);

        for (int i=0; i<numPoints; i++) {
            CGPoint p = (CGPoint)(point_list[i]);
            [result addObject:[NSValue valueWithCGPoint:p]];
        }

// result has your points!

Здесь ссылка на библиотеку геометрии Boost: http://www.boost.org/doc/libs/1_47_0/libs/geometry/doc/html/geometry/introduction.html

Ответ 2

Использовать CGContextSetLineDash

Цель этой функции - создать пунктирную линию, но вы можете использовать ее для получения меньших сегментов. начальная точка каждого сегмента может рассматриваться как точки.

CGSize bbSize = CGPathGetBoundingBox(path).size;
UIGraphicsBeginImageContext(bbSize);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(ctx, 1.0);
CGContextAddPath(ctx, path);
CGContextSetLineDash(ctx, phase, lengths, count);
CGContextReplacePathWithStrokedPath(ctx);
result = CGContextCopyPath(ctx);
UIGraphicsEndImageContext();

Ответ 3

Если вы хотите работать с элементами moveto, lineto и curveto пути, используйте CGPathApply. Вы передаете это указатель на функцию в вашей программе, и она вызывает эту функцию один раз для каждого элемента пути.

К сожалению, нет способа просто запросить каждый элемент, например, с AppKit NSBezierPath. Функция является единственным способом.

Если вы хотите определить каждый пиксель, пересекаемый по пути, слишком плохой - это не практично, и я даже не могу думать о том, зачем вам нужна эта информация. Некоторые контексты, такие как контексты PDF, даже не имеют пикселей; в этих случаях любой вопрос, связанный с пикселями, является нелогичным.

Ответ 4

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

См. Получение информации о путях Кварца для списка функций, которые вы можете использовать для запроса объекта CGPath. К сожалению, кажется, что самая полезная информация, которую вы собираетесь получить, - это CGPathContainsPoint(), которая сообщает только, является ли данная точка содержащихся в области пути.

Ответ 5

Если у вас нет другого решения для математического извлечения всех точек кривой.

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

Ответ 6

Я предполагаю, что вы после чего-то эквивалентны классу Java2D FlatteningPathIterator. Например, Java2D path.getPathIterator(null, 1.0) возвращает итератор только сегментов "lineTo", даже если исходный путь имеет кривыеTo и quadTo, двойной аргумент управляет "плоскостностью", что дает вам простой способ вычисления любой точки на кривой. Я ищу то же самое в Cocoa, но ничего не нашел. Если вы найдете решение, сообщите мне. Существуют критические импликации (например, http://sourceforge.net/projects/curves/), которые можно портировать, но всегда существует риск, что если вы не будете использовать то же самое алгоритм как Cocoa, тогда могут быть ошибки между вашей интерполяцией и поглаженным NSBezierPath/CGPath.