2010-03-23 173 views
9

我正在使用route-me的框架来处理位置。 在此代码中,两个标记(点)之间的路径将绘制为一条线。用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); 
} 

+0

我通过http://www.codeguru.com/cpp/gm/gdi/article.php/c3683得到它前一阵子反正thansk的答案格尔茨 – Pete 2010-04-16 12:34:18

+0

皮特,它可能是很好的你将答案标记为已接受,或者将答案张贴为答案,然后接受答案。 – 2012-03-14 10:47:51

+0

@Pete你为什么不标记正确的答案(我的意思是Friedhelm的)? – yas375 2012-11-12 13:22:51

回答

5

“如果我想在该行的中间(或顶部)添加箭头,以便它指向的方向,我应该添加什么代码”一旦你在你的路上有两个点,实际的三角形/箭头的绘制很容易。

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

获得积分有点棘手。你说道路是一条线,而不是曲线或一系列曲线。这使它更容易。

使用CGPathApply选取路径上的两个点。可能这是最后两点,其中一个可能是kCGPathElementMoveToPoint,另一个可能是kCGPathElementAddLineToPoint。让mx,我是第一个点,nx,ny是第二个,所以箭头将从m指向n。

假设你想要在行末端的箭头,bx,从上面将等于nx,ny在行上。在mx,my和nx,ny之间选择一个点dx,dy来计算其他点。

现在计算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,而是我先前的点或移动,它将成为最终曲线的最终控制点。每个控制点位于与曲线相切并通过相邻点的线上。

2

我发现这个问题,因为我有同样的。我拿了drawnonward的例子,它是如此接近......但随着COS和罪恶的翻转,我能得到它的工作:

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;

谢谢去绘制!

20
- (void) drawLine: (CGContextRef) context from: (CGPoint) from to: (CGPoint) to 
{ 
    double slopy, cosy, siny; 
    // Arrow size 
    double length = 10.0; 
    double width = 5.0; 

    slopy = atan2((from.y - to.y), (from.x - to.x)); 
    cosy = cos(slopy); 
    siny = sin(slopy); 

    //draw a line between the 2 endpoint 
    CGContextMoveToPoint(context, from.x - length * cosy, from.y - length * siny); 
    CGContextAddLineToPoint(context, to.x + length * cosy, to.y + length * siny); 
    //paints a line along the current path 
    CGContextStrokePath(context); 

    //here is the tough part - actually drawing the arrows 
    //a total of 6 lines drawn to make the arrow shape 
    CGContextMoveToPoint(context, from.x, from.y); 
    CGContextAddLineToPoint(context, 
         from.x + (- length * cosy - (width/2.0 * siny)), 
         from.y + (- length * siny + (width/2.0 * cosy))); 
    CGContextAddLineToPoint(context, 
         from.x + (- length * cosy + (width/2.0 * siny)), 
         from.y - (width/2.0 * cosy + length * siny)); 
    CGContextClosePath(context); 
    CGContextStrokePath(context); 

    /*/-------------similarly the the other end-------------/*/ 
    CGContextMoveToPoint(context, to.x, to.y); 
    CGContextAddLineToPoint(context, 
         to.x + (length * cosy - (width/2.0 * siny)), 
         to.y + (length * siny + (width/2.0 * cosy))); 
    CGContextAddLineToPoint(context, 
         to.x + (length * cosy + width/2.0 * siny), 
         to.y - (width/2.0 * cosy - length * siny)); 
    CGContextClosePath(context); 
    CGContextStrokePath(context); 
}