iphone кварц, рисующий 2 линии друг на друге, вызывает эффект червя - PullRequest
1 голос
/ 14 января 2010

Я использую Quartz-2D для iPhone, чтобы отобразить маршрут на карте. Маршрут окрашен в зависимости от температуры. Поскольку некоторые улицы окрашены в желтый цвет, я использую немного более толстую черную линию под линией маршрута, чтобы создать эффект границы, чтобы желтые части маршрута были заметны на желтых улицах. Но даже если черная линия такая же толстая, как и линия маршрута, весь маршрут выглядит как червь (очень уродливый). Я думал, что это потому, что я рисовал линии от путевой точки к путевой точке, вместо этого используя последнюю путевую точку в качестве следующей начальной путевой точки. Таким образом, если пропущена пара путевых точек, маршрут все равно не будет обрезан.

Что мне нужно сделать, чтобы обе строки отображались без эффекта червя?

-(void) drawRect:(CGRect) rect
{
CSRouteAnnotation* routeAnnotation = (CSRouteAnnotation*)self.routeView.annotation;

// only draw our lines if we're not int he moddie of a transition and we 
// acutally have some points to draw. 
if(!self.hidden && nil != routeAnnotation.points && routeAnnotation.points.count >   0)
{
    CGContextRef context = UIGraphicsGetCurrentContext(); 

    Waypoint* fromWaypoint = [[Waypoint alloc] initWithDictionary:[routeAnnotation.points objectAtIndex:0]];
    Waypoint* toWaypoint;

    for(int idx = 1; idx < routeAnnotation.points.count; idx++)
    {
        toWaypoint = [[Waypoint alloc] initWithDictionary:[routeAnnotation.points objectAtIndex:idx]];


        CLLocation* fromLocation = [fromWaypoint getLocation];
        CGPoint fromPoint = [self.routeView.mapView convertCoordinate:fromLocation.coordinate toPointToView:self];

        CLLocation* toLocation = [toWaypoint getLocation];
        CGPoint toPoint = [self.routeView.mapView convertCoordinate:toLocation.coordinate toPointToView:self];

        routeAnnotation.lineColor = [fromWaypoint.weather getTemperatureColor];

        CGContextBeginPath(context);
        CGContextSetLineWidth(context, 3.0);
        CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
        CGContextMoveToPoint(context, fromPoint.x, fromPoint.y);
        CGContextAddLineToPoint(context, toPoint.x, toPoint.y);
        CGContextStrokePath(context);
        CGContextClosePath(context);

        CGContextBeginPath(context);
        CGContextSetLineWidth(context, 3.0);
        CGContextSetStrokeColorWithColor(context,    routeAnnotation.lineColor.CGColor);
        CGContextMoveToPoint(context, fromPoint.x, fromPoint.y);
        CGContextAddLineToPoint(context, toPoint.x, toPoint.y);
        CGContextStrokePath(context);
        CGContextClosePath(context);


        fromWaypoint = toWaypoint;
    }

    [fromWaypoint release];
    [toWaypoint release];       
}
}

Также я получаю

<Error>: CGContextClosePath: no current point.

ошибка, которую я считаю ерундой.

Пожалуйста, подскажите мне! :)


Ответы [ 4 ]

0 голосов
/ 15 января 2010

Кроме того, я получаю

: CGContextClosePath: нет текущей точки.

Поглаживание пути завершает текущий контекст пути.

0 голосов
/ 14 января 2010

Вместо того, чтобы рисовать две линии, не могли бы вы нарисовать одну и использовать способность Теней ?

0 голосов
/ 14 января 2010

Спасибо, ребята! Таким образом, простое добавление тени или заглавных букв не помогло, эффект остался прежним. Тем не менее, я просто немного поиграл с кодом, и оказалось, что если я рисую обе линии в полном пути по отдельности (в двух циклах), эффект исчезнет! Затем я добавил квадратные заглавные буквы к фоновой линии, чтобы сделать ее немного лучше.

Теперь единственное, что меня интересует, это ... как это объяснить? Вот новый код, позже я его оптимизирую ...

-(void) drawRect:(CGRect) rect {
CSRouteAnnotation* routeAnnotation = (CSRouteAnnotation*)self.routeView.annotation;

// only draw our lines if we're not int he moddie of a transition and we 
// acutally have some points to draw. 
if(!self.hidden && nil != routeAnnotation.points && routeAnnotation.points.count > 0)
{
    CGContextRef context = UIGraphicsGetCurrentContext(); 


    Waypoint* fromWaypoint = [[Waypoint alloc] initWithDictionary:[routeAnnotation.points objectAtIndex:0]];
    Waypoint* toWaypoint;

    for(int idx = 1; idx < routeAnnotation.points.count; idx++)
    {
        toWaypoint = [[Waypoint alloc] initWithDictionary:[routeAnnotation.points objectAtIndex:idx]];


        CLLocation* fromLocation = [fromWaypoint getLocation];
        CGPoint fromPoint = [self.routeView.mapView convertCoordinate:fromLocation.coordinate toPointToView:self];

        CLLocation* toLocation = [toWaypoint getLocation];
        CGPoint toPoint = [self.routeView.mapView convertCoordinate:toLocation.coordinate toPointToView:self];

        routeAnnotation.lineColor = [fromWaypoint.weather getTemperatureColor];

        CGContextBeginPath(context);
        CGContextSetLineWidth(context, 3.5);
        CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
        CGContextSetLineCap(context, kCGLineCapSquare);
        CGContextMoveToPoint(context, fromPoint.x, fromPoint.y);
        CGContextAddLineToPoint(context, toPoint.x, toPoint.y);
        CGContextStrokePath(context);
        CGContextClosePath(context);

        fromWaypoint = toWaypoint;

    }

    // zweite for schleife
    for(int idx = 1; idx < routeAnnotation.points.count; idx++)
    {
        toWaypoint = [[Waypoint alloc] initWithDictionary:[routeAnnotation.points objectAtIndex:idx]];


        CLLocation* fromLocation = [fromWaypoint getLocation];
        CGPoint fromPoint = [self.routeView.mapView convertCoordinate:fromLocation.coordinate toPointToView:self];

        CLLocation* toLocation = [toWaypoint getLocation];
        CGPoint toPoint = [self.routeView.mapView convertCoordinate:toLocation.coordinate toPointToView:self];

        routeAnnotation.lineColor = [fromWaypoint.weather getTemperatureColor];

        CGContextBeginPath(context);

        CGContextSetLineWidth(context, 3.0);
        CGContextSetStrokeColorWithColor(context, routeAnnotation.lineColor.CGColor);
        CGContextSetLineCap(context, kCGLineCapSquare );
        CGContextMoveToPoint(context, fromPoint.x, fromPoint.y);
        CGContextAddLineToPoint(context, toPoint.x, toPoint.y);
        CGContextStrokePath(context);
        CGContextClosePath(context);

    }

    [fromWaypoint release];
   }
}       
0 голосов
/ 14 января 2010

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

UPDATE: Я вижу, что происходит сейчас. Это просто «фоновая» линия, перекрывающая пиксели, покрытые предыдущей линией «фон» + «передний план». Ваше изменение рисовать все «фоновые» линии, а затем все «передние» линии позволяет избежать этой проблемы. Ваши линии по-прежнему перекрывают некоторые пиксели, но только одного цвета, поэтому вы не заметите. (Обратите внимание, что большинство стилей конца строки расширяются за фактическую точку линии, делая эффект более выраженным - больше перекрывающихся пикселей)

...