Drawing triangle/arrow on a line with CGContext

swift draw line on uiview
swift draw line between two points
draw line on image swift
swift draw rectangle
xcode draw line storyboard
cgcontext draw
swift draw shapes
swift cgpath draw line

I am using the framework of route-me for working with locations. In this code the path between two markers(points) will be drawn as a line.

My Question: "What code should I add if I want to add an arrow in the middle(or top) of the line, so that it points the direction"

Thanks


- (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);
}

- (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);
}

Programming IOS 4: Fundamentals of IPhone, IPad, and IPod Touch , A simple path drawing A path can be compound, meaning that it consists of or calling CGContext- BeginPath), you pick up the imaginary pen and move it to a (by default) vertical line, the shaft of the arrow CGContextMoveToPoint(con, 100, triangle, the point of the arrow CGContextSetFillColorWithColor(con, [[UIColor​  Now, you need to actually draw the line showing the splitter. To draw a line between A and B, you first move to point A, which won’t cause Core Graphics to draw anything. You then add a line to point B which adds the line from point A to point B into the context. You can then call strokePath() to stroke the line.

The drawing of the actual triangle/arrow is easy once you have two points on your path.

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

Getting the points is a little more tricky. You said path was a line, as opposed to a curve or series of curves. That makes it easier.

Use CGPathApply to pick two points on the path. Probably, this is the last two points, one of which may be kCGPathElementMoveToPoint and the other will be kCGPathElementAddLineToPoint. Let mx,my be the first point and nx,ny be the second, so the arrow will point from m towards n.

Assuming you want the arrow at the tip of the line, bx,by from above will equal nx,ny on the line. Choose a point dx,dy between mx,my and nx,ny to calculate the other points.

Now calculate ax,ay and cx,cy such that they are on a line with dx,dy and equidistant from path. The following should be close, although I probably got some signs wrong:

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;

Length is the distance from the tip of the arrow to the base, and width is distance from the shaft to the barbs, or half the breadth of the arrow head.

If path is a curve, then instead of finding mx,my as the previous point or move, it will be the final control point of the final curve. Each control point is on a line tangent to the curve and passing through the adjacent point.

Programming IOS 6, The very strange behavior ofCGContextClearRect When drawing directly into a view Yet these are instances of the same UIView subclass, drawn with exactly the default) vertical line, the shaft of the arrow CGContextMoveToPoint(con, 100, 20); CGContextStrokePath(con); // draw a red triangle, the point of the arrow  Drawing straight lines or arrows To add a straight line or arrow to the graph window: Click on the Line tool or Arrow tool . Click-and-drag at the desired location in the graph window. Release the mouse button and the line or arrow is displayed. To draw a vertical or horizontal line or arrow, press the SHIFT key as you drag with the Line tool or Arrow tool. You will see that the line snaps to the horizontal or vertical.

I found this question as I had the same. I took drawnonward's example and it was so close... But with a flipping of cos and sin, I was able to get it to work:

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;

Once I did that, my arrows were pointed exactly the wrong way. So I added that second line (r += M_PI;)

Thanks go to drawnonward!

Programming IOS 7, A simple path drawing A path can be compound, meaning that it consists of graphics context CGContextRef con = UIGraphicsGetCurrentContext(); // draw a black (by default) vertical line, the shaft of the arrow CGContextMoveToPoint(con, 100, 20); CGContextStrokePath(con); // draw a red triangle, the point of the arrow  dabbler:. True, I just tried it. But it won't convert a line into an arrow. If there is an object type that is an arrow then you can write a little script that changes the renamed line into an arrow and activate the script with a shortcut key.That is quicker than waiting for MetaQuotes to add a feature to the now obsolescent MQL4.

And here is Swift 4+ version for Friedhelm Brügge answer: (I'll draw it on image)

func drawArrow(image: UIImage, ptSrc: CGPoint, ptDest: CGPoint) {

        // create context with image size
        UIGraphicsBeginImageContext(image.size)
        let context = UIGraphicsGetCurrentContext()

        // draw current image to the context
        image.draw(in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))

        var slopY: CGFloat, cosY: CGFloat, sinY: CGFloat;
        // Arrow size
        let length: CGFloat = 35.0;
        let width: CGFloat = 35.0;

        slopY = atan2((ptSrc.y - ptDest.y), (ptSrc.x - ptDest.x));
        cosY = cos(slopY);
        sinY = sin(slopY);

        //here is the tough part - actually drawing the arrows
        //a total of 6 lines drawn to make the arrow shape
        context?.setFillColor(UIColor.white.cgColor)
        context?.move(to: CGPoint(x: ptSrc.x, y: ptSrc.y))
        context?.addLine(to: CGPoint(x: ptSrc.x + ( -length * cosY - ( width / 2.0 * sinY )), y: ptSrc.y + ( -length * sinY + ( width / 2.0 * cosY ))))
        context?.addLine(to: CGPoint(x: ptSrc.x + (-length * cosY + ( width / 2.0 * sinY )), y: ptSrc.y - (width / 2.0 * cosY + length * sinY )))
        context?.closePath()
        context?.fillPath()

        context?.move(to: CGPoint(x: ptSrc.x, y: ptSrc.y))
        context?.addLine(to: CGPoint(x: ptDest.x +  (length * cosY - ( width / 2.0 * sinY )), y: ptDest.y +  (length * sinY + ( width / 2.0 * cosY ))))
        context?.addLine(to: CGPoint(x: ptDest.x +  (length * cosY + width / 2.0 * sinY), y: ptDest.y -  (width / 2.0 * cosY - length * sinY)))
        context?.closePath()
        context?.fillPath()

        // draw current context to image view
        imgView.image = UIGraphicsGetImageFromCurrentImageContext()

        //close context
        UIGraphicsEndImageContext()
    }

Drawing+triangle+arrow+on+a+line+with+CGContext, How to draw lines in Core Graphics: move(to:) and addLine(to:) to set up a context and choose a color, you can draw a triangle with this code: LaTeX arrows. Latex provides a huge number of different arrow symbols. Arrows would be used within math enviroment. If you want to use them in text just put the arrow command between two $ like this example: $\uparrow$ now you got an up arrow in text.

How to draw lines in Core Graphics: move(to:) and addLine(to , iphone - Drawing triangle/arrow on a line with CGContext - Stack Overf iphone core-graphics iphone - Draw Line using CGContext - Stack Overflow. Select the More arrow and then select the Freeform tool, the Arc tool, or the Line tool. To draw the first segment of the shape, drag on the page. Select the vertex ( ) at the end of the last segment you added, and drag to draw the next segment.

iphone, This is because iOS sets up the correct CGContext for drawing into a view immediately prior to calling draw(_:) . Now that you  OpenCV provides many drawing functions to draw geometric shapes and write text on images. Let’s see some of the drawing functions and draw geometric shapes on images using OpenCV. Some of the drawing functions are : cv2.line() : Used to draw line on an image. cv2.rectangle() : Used to draw rectangle on an image.

Core Graphics Tutorial: Lines, Rectangles, and Gradients , Core Graphics is Apple's vector drawing framework. The paths can be based on lines, curves, rectangles or a series of connected points. The red arrow shows where your arc will start and end, drawing in a clockwise  This drawing triangle is very useful for drafting and for use in layout in the shop. I might have prefered that it was a bright color instead of grey, simply so that it can be spotted more quickly. BOTTOM LINE: Four stars full review

Comments
  • I got it a while ago by codeguru.com/cpp/g-m/gdi/article.php/c3683 Anyway thansk for the answers Greetz
  • Pete, it may be nice of you to mark an answer as accepted nonetheless, or post your answer as an answer and then accept that.
  • @Pete why didn't you mark the right answer (I mean Friedhelm's)?