Рисование треугольника/стрелки на строке с CGContext

Я использую платформу маршрута - меня для работы с местоположениями. В этом коде путь между двумя маркерами (точки) будет оттянут как строка.

Мой Вопрос: "Что код должен я добавлять, хочу ли я добавить стрелку в середине (или вершина) строки, так, чтобы это указало на направление"

Спасибо



- (void)drawInContext:(CGContextRef)theContext
{
    renderedScale = [contents metersPerPixel];

    float scale = 1.0f / [contents metersPerPixel];

    float scaledLineWidth = lineWidth;
    if(!scaleLineWidth) {
        scaledLineWidth *= renderedScale;
    }
    //NSLog(@"line width = %f, content scale = %f", scaledLineWidth, renderedScale);

    CGContextScaleCTM(theContext, scale, scale);

    CGContextBeginPath(theContext);
    CGContextAddPath(theContext, path);

    CGContextSetLineWidth(theContext, scaledLineWidth);
    CGContextSetStrokeColorWithColor(theContext, [lineColor CGColor]);
    CGContextSetFillColorWithColor(theContext, [fillColor CGColor]);

    // according to Apple's documentation, DrawPath closes the path if it's a filled style, so a call to ClosePath isn't necessary
    CGContextDrawPath(theContext, drawingMode);
}

11
задан Pete 23 March 2010 в 13:49
поделиться

2 ответа

Нарисовать настоящий треугольник / стрелку легко, если на вашем пути есть две точки.

CGContextMoveToPoint( context , ax , ay );
CGContextAddLineToPoint( context , bx , by );
CGContextAddLineToPoint( context , cx , cy );
CGContextClosePath( context ); // for triangle

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

Используйте CGPathApply, чтобы указать две точки на пути. Вероятно, это две последние точки, одна из которых может быть kCGPathElementMoveToPoint, а другая - kCGPathElementAddLineToPoint. Пусть mx, my будет первой точкой, а nx, ny - второй, поэтому стрелка будет указывать от m к n.

Предположим, вы хотите, чтобы стрелка на конце линии, bx, сверху была равна nx, ny на линии. Выберите точку dx, dy между mx, my и nx, ny, чтобы вычислить другие точки.

Теперь вычислите ax, ay и cx, cy так, чтобы они находились на линии с dx, dy и на равном расстоянии от пути. Следующее должно быть близко, хотя я, вероятно, ошибся в некоторых признаках:

r = atan2( ny - my , nx - mx );
bx = nx;
by = ny;
dx = bx + sin( r ) * length;
dy = by + cos( r ) * length;
r += M_PI_2; // perpendicular to path
ax = dx + sin( r ) * width;
ay = dy + cos( r ) * width;
cx = dx - sin( r ) * width;
cy = dy - cos( r ) * width;

Длина - это расстояние от кончика стрелы до основания, а ширина - это расстояние от стержня до зазубрин, или половина ширины наконечника стрелы. .

Если путь является кривой, то вместо нахождения mx, my в качестве предыдущей точки или перемещения, это будет последняя контрольная точка последней кривой. Каждая контрольная точка находится на линии, касательной к кривой и проходящей через соседнюю точку.

6
ответ дан 3 December 2019 в 03:17
поделиться

Я нашел этот вопрос, как и у меня был такой же. Я взял пример drawonward, и он был так близок ... Но, перевернув cos и sin, я смог заставить его работать:

r = atan2( ny - my , nx - mx );
r += M_PI;
bx = nx;
by = ny;
dx = bx + cos( r ) * length;
dy = by + sin( r ) * length;
r += M_PI_2; // perpendicular to path
ax = dx + cos( r ) * width;
ay = dy + sin( r ) * width;
cx = dx - cos( r ) * width;
cy = dy - sin( r ) * width;

Как только я это сделал, мои стрелы были направлены точно не в ту сторону. Итак, я добавил эту вторую строку ( r + = M_PI; )

Спасибо, go to drawonward!

2
ответ дан 3 December 2019 в 03:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: